diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index c9f4be61b2666..9215543ab67e6 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -254,7 +254,11 @@ def PtrStrideOp : CIR_Op<"ptr_stride", ``` }]; - let arguments = (ins CIR_PointerType:$base, PrimitiveInt:$stride); + let arguments = (ins + CIR_PointerType:$base, + CIR_AnyFundamentalIntType:$stride + ); + let results = (outs CIR_PointerType:$result); let assemblyFormat = [{ diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td new file mode 100644 index 0000000000000..3b8cb20da8edb --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypeConstraints.td @@ -0,0 +1,113 @@ +//===----------------------------------------------------------------------===// +// +// 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 defines the CIR dialect type constraints. +// +//===----------------------------------------------------------------------===// + +#ifndef CLANG_CIR_DIALECT_IR_CIRTYPECONSTRAINTS_TD +#define CLANG_CIR_DIALECT_IR_CIRTYPECONSTRAINTS_TD + +include "mlir/IR/Constraints.td" +include "mlir/IR/CommonTypeConstraints.td" + +class CIR_IsTypePred : CPred<"::mlir::isa<" # type # ">($_self)">; + +class CIR_TypeBase + : Type, summary, type>; + +class CIR_CastSelfToType + : SubstLeaves<"$_self", "::mlir::cast<" # type # ">($_self)", pred>; + +class CIR_CastedSelfsToType preds> + : And)>; + +class CIR_ConfinedType preds, string summary = ""> + : Type]>, + summary, type.cppType>; + +//===----------------------------------------------------------------------===// +// IntType predicates +//===----------------------------------------------------------------------===// + +def CIR_AnyIntType : CIR_TypeBase<"::cir::IntType", "integer type">; + +def CIR_AnyUIntType : CIR_ConfinedType], "unsigned integer type">; + +def CIR_AnySIntType : CIR_ConfinedType], "signed integer type">; + +class CIR_HasWidthPred : CPred<"$_self.getWidth() == " # width>; + +def CIR_HasFundamentalIntWidthPred + : CPred<"::cir::isValidFundamentalIntWidth($_self.getWidth())">; + +class CIR_IntOfWidthsPred widths> + : Or)>; + +class CIR_IntOfWidths widths> + : CIR_ConfinedType], + "integer type of widths " # !interleave(widths, "/")>; + +class CIR_SIntOfWidths widths> + : CIR_ConfinedType], + "signed integer type of widths " # !interleave(widths, "/")>; + +class CIR_UIntOfWidths widths> + : CIR_ConfinedType], + "unsigned integer type of widths " # !interleave(widths, "/")>; + +class CIR_UInt + : CIR_ConfinedType], + width # "-bit unsigned integer">, + BuildableType<"$_builder.getType<" # cppType # ">(" # + width # ", /*isSigned=*/false)">; + +def CIR_UInt1 : CIR_UInt<1>; +def CIR_UInt8 : CIR_UInt<8>; +def CIR_UInt16 : CIR_UInt<16>; +def CIR_UInt32 : CIR_UInt<32>; +def CIR_UInt64 : CIR_UInt<64>; +def CIR_UInt128 : CIR_UInt<128>; + +class CIR_SInt + : CIR_ConfinedType], + width # "-bit signed integer">, + BuildableType<"$_builder.getType<" # cppType # ">(" # + width # ", /*isSigned=*/true)">; + +def CIR_SInt1 : CIR_SInt<1>; +def CIR_SInt8 : CIR_SInt<8>; +def CIR_SInt16 : CIR_SInt<16>; +def CIR_SInt32 : CIR_SInt<32>; +def CIR_SInt64 : CIR_SInt<64>; +def CIR_SInt128 : CIR_SInt<128>; + +// Fundamental integer types represent standard source-level integer types that +// have a specified set of admissible bitwidths (8, 16, 32, 64). + +def CIR_AnyFundamentalIntType + : CIR_ConfinedType { + let cppFunctionName = "isFundamentalIntType"; +} + +def CIR_AnyFundamentalUIntType + : CIR_ConfinedType { + let cppFunctionName = "isFundamentalUIntType"; +} + +def CIR_AnyFundamentalSIntType + : CIR_ConfinedType { + let cppFunctionName = "isFundamentalSIntType"; +} + +#endif // CLANG_CIR_DIALECT_IR_CIRTYPECONSTRAINTS_TD diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h index 074b8d07e0e80..2e32765c1e941 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h @@ -24,6 +24,8 @@ namespace detail { struct RecordTypeStorage; } // namespace detail +bool isValidFundamentalIntWidth(unsigned width); + bool isAnyFloatingPointType(mlir::Type t); bool isFPOrFPVectorTy(mlir::Type); @@ -33,6 +35,12 @@ bool isFPOrFPVectorTy(mlir::Type); // CIR Dialect Tablegen'd Types //===----------------------------------------------------------------------===// +namespace cir { + +#include "clang/CIR/Dialect/IR/CIRTypeConstraints.h.inc" + +} // namespace cir + #define GET_TYPEDEF_CLASSES #include "clang/CIR/Dialect/IR/CIROpsTypes.h.inc" diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td index 6ca6fbeeb6165..d9f05c9aea63d 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -14,6 +14,7 @@ #define MLIR_CIR_DIALECT_CIR_TYPES include "clang/CIR/Dialect/IR/CIRDialect.td" +include "clang/CIR/Dialect/IR/CIRTypeConstraints.td" include "clang/CIR/Interfaces/CIRFPTypeInterface.td" include "mlir/Interfaces/DataLayoutInterfaces.td" include "mlir/IR/AttrTypeBase.td" @@ -41,7 +42,7 @@ def CIR_IntType : CIR_Type<"Int", "int", such as `__int128`, and arbitrary width types such as `_BitInt(n)`. Those integer types that are directly available in C/C++ standard are called - primitive integer types. Said types are: `signed char`, `short`, `int`, + fundamental integer types. Said types are: `signed char`, `short`, `int`, `long`, `long long`, and their unsigned variations. }]; let parameters = (ins "unsigned":$width, "bool":$isSigned); @@ -55,81 +56,26 @@ def CIR_IntType : CIR_Type<"Int", "int", std::string getAlias() const { return (isSigned() ? 's' : 'u') + std::to_string(getWidth()) + 'i'; } - /// Return true if this is a primitive integer type (i.e. signed or unsigned - /// integer types whose bit width is 8, 16, 32, or 64). - bool isPrimitive() const { - return isValidPrimitiveIntBitwidth(getWidth()); + /// Return true if this is a fundamental integer type (i.e. signed or + /// unsigned integer types whose bit width is 8, 16, 32, or 64). + bool isFundamental() const { + return isFundamentalIntType(*this); } - bool isSignedPrimitive() const { - return isPrimitive() && isSigned(); + bool isSignedFundamental() const { + return isFundamentalSIntType(*this); + } + bool isUnsignedFundamental() const { + return isFundamentalUIntType(*this); } /// Returns a minimum bitwidth of cir::IntType static unsigned minBitwidth() { return 1; } /// Returns a maximum bitwidth of cir::IntType static unsigned maxBitwidth() { return 128; } - - /// Returns true if cir::IntType that represents a primitive integer type - /// can be constructed from the provided bitwidth. - static bool isValidPrimitiveIntBitwidth(unsigned width) { - return width == 8 || width == 16 || width == 32 || width == 64; - } }]; let genVerifyDecl = 1; } -// Constraints - -// Unsigned integer type of a specific width. -class UInt - : Type($_self)">, - CPred<"::mlir::cast<::cir::IntType>($_self).isUnsigned()">, - CPred<"::mlir::cast<::cir::IntType>($_self).getWidth() == " # width> - ]>, width # "-bit unsigned integer", "::cir::IntType">, - BuildableType< - "cir::IntType::get($_builder.getContext(), " - # width # ", /*isSigned=*/false)"> { - int bitwidth = width; -} - -def UInt1 : UInt<1>; -def UInt8 : UInt<8>; -def UInt16 : UInt<16>; -def UInt32 : UInt<32>; -def UInt64 : UInt<64>; - -// Signed integer type of a specific width. -class SInt - : Type($_self)">, - CPred<"::mlir::cast<::cir::IntType>($_self).isSigned()">, - CPred<"::mlir::cast<::cir::IntType>($_self).getWidth() == " # width> - ]>, width # "-bit signed integer", "::cir::IntType">, - BuildableType< - "cir::IntType::get($_builder.getContext(), " - # width # ", /*isSigned=*/true)"> { - int bitwidth = width; -} - -def SInt1 : SInt<1>; -def SInt8 : SInt<8>; -def SInt16 : SInt<16>; -def SInt32 : SInt<32>; -def SInt64 : SInt<64>; - -def PrimitiveUInt - : AnyTypeOf<[UInt8, UInt16, UInt32, UInt64], "primitive unsigned int", - "::cir::IntType">; - -def PrimitiveSInt - : AnyTypeOf<[SInt8, SInt16, SInt32, SInt64], "primitive signed int", - "::cir::IntType">; - -def PrimitiveInt - : AnyTypeOf<[UInt8, UInt16, UInt32, UInt64, SInt8, SInt16, SInt32, SInt64], - "primitive int", "::cir::IntType">; - //===----------------------------------------------------------------------===// // FloatType //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt b/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt index 39292fb541daa..6e6d59ea5dadb 100644 --- a/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt +++ b/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt @@ -19,3 +19,9 @@ mlir_tablegen(CIROpsAttributes.cpp.inc -gen-attrdef-defs) mlir_tablegen(CIROpsEnums.h.inc -gen-enum-decls) mlir_tablegen(CIROpsEnums.cpp.inc -gen-enum-defs) add_public_tablegen_target(MLIRCIREnumsGen) + +set(LLVM_TARGET_DEFINITIONS CIRTypeConstraints.td) +mlir_tablegen(CIRTypeConstraints.h.inc -gen-type-constraint-decls) +mlir_tablegen(CIRTypeConstraints.cpp.inc -gen-type-constraint-defs) +add_public_tablegen_target(MLIRCIRTypeConstraintsIncGen) +add_dependencies(mlir-headers MLIRCIRTypeConstraintsIncGen) diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp index ce85e48c4555e..7d960c21d7251 100644 --- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp @@ -33,6 +33,12 @@ static void printFuncTypeParams(mlir::AsmPrinter &p, // Get autogenerated stuff //===----------------------------------------------------------------------===// +namespace cir { + +#include "clang/CIR/Dialect/IR/CIRTypeConstraints.cpp.inc" + +} // namespace cir + #define GET_TYPEDEF_CLASSES #include "clang/CIR/Dialect/IR/CIROpsTypes.cpp.inc" @@ -424,6 +430,10 @@ IntType::verify(llvm::function_ref emitError, return mlir::success(); } +bool cir::isValidFundamentalIntWidth(unsigned width) { + return width == 8 || width == 16 || width == 32 || width == 64; +} + //===----------------------------------------------------------------------===// // Floating-point type definitions //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Dialect/IR/CMakeLists.txt b/clang/lib/CIR/Dialect/IR/CMakeLists.txt index 97a530d8c76d6..e5256bf961f46 100644 --- a/clang/lib/CIR/Dialect/IR/CMakeLists.txt +++ b/clang/lib/CIR/Dialect/IR/CMakeLists.txt @@ -6,6 +6,7 @@ add_clang_library(MLIRCIR DEPENDS MLIRCIROpsIncGen + MLIRCIRTypeConstraintsIncGen MLIRCIREnumsGen MLIRCIROpInterfacesIncGen MLIRCIRLoopOpInterfaceIncGen