|
| 1 | +//===- CIRTypes.td - CIR dialect types ---------------------*- tablegen -*-===// |
| 2 | +// |
| 3 | +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | +// See https://llvm.org/LICENSE.txt for license information. |
| 5 | +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | +// |
| 7 | +//===----------------------------------------------------------------------===// |
| 8 | +// |
| 9 | +// This file declares the CIR dialect types. |
| 10 | +// |
| 11 | +//===----------------------------------------------------------------------===// |
| 12 | + |
| 13 | +#ifndef MLIR_CIR_DIALECT_CIR_TYPES |
| 14 | +#define MLIR_CIR_DIALECT_CIR_TYPES |
| 15 | + |
| 16 | +include "clang/CIR/Dialect/IR/CIRDialect.td" |
| 17 | +include "mlir/Interfaces/DataLayoutInterfaces.td" |
| 18 | +include "mlir/IR/AttrTypeBase.td" |
| 19 | + |
| 20 | +//===----------------------------------------------------------------------===// |
| 21 | +// CIR Types |
| 22 | +//===----------------------------------------------------------------------===// |
| 23 | + |
| 24 | +class CIR_Type<string name, string typeMnemonic, list<Trait> traits = [], |
| 25 | + string baseCppClass = "::mlir::Type"> |
| 26 | + : TypeDef<CIR_Dialect, name, traits, baseCppClass> { |
| 27 | + let mnemonic = typeMnemonic; |
| 28 | +} |
| 29 | + |
| 30 | +//===----------------------------------------------------------------------===// |
| 31 | +// IntType |
| 32 | +//===----------------------------------------------------------------------===// |
| 33 | + |
| 34 | +def CIR_IntType : CIR_Type<"Int", "int", |
| 35 | + [DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> { |
| 36 | + let summary = "Integer type with arbitrary precision up to a fixed limit"; |
| 37 | + let description = [{ |
| 38 | + CIR type that represents integer types with arbitrary precision, including |
| 39 | + standard integral types such as `int` and `long`, extended integral types |
| 40 | + such as `__int128`, and arbitrary width types such as `_BitInt(n)`. |
| 41 | + |
| 42 | + Those integer types that are directly available in C/C++ standard are called |
| 43 | + primitive integer types. Said types are: `signed char`, `short`, `int`, |
| 44 | + `long`, `long long`, and their unsigned variations. |
| 45 | + }]; |
| 46 | + let parameters = (ins "unsigned":$width, "bool":$isSigned); |
| 47 | + let hasCustomAssemblyFormat = 1; |
| 48 | + let extraClassDeclaration = [{ |
| 49 | + /// Return true if this is a signed integer type. |
| 50 | + bool isSigned() const { return getIsSigned(); } |
| 51 | + /// Return true if this is an unsigned integer type. |
| 52 | + bool isUnsigned() const { return !getIsSigned(); } |
| 53 | + /// Return type alias. |
| 54 | + std::string getAlias() const { |
| 55 | + return (isSigned() ? 's' : 'u') + std::to_string(getWidth()) + 'i'; |
| 56 | + } |
| 57 | + /// Return true if this is a primitive integer type (i.e. signed or unsigned |
| 58 | + /// integer types whose bit width is 8, 16, 32, or 64). |
| 59 | + bool isPrimitive() const { |
| 60 | + return isValidPrimitiveIntBitwidth(getWidth()); |
| 61 | + } |
| 62 | + bool isSignedPrimitive() const { |
| 63 | + return isPrimitive() && isSigned(); |
| 64 | + } |
| 65 | + |
| 66 | + /// Returns a minimum bitwidth of cir::IntType |
| 67 | + static unsigned minBitwidth() { return 1; } |
| 68 | + /// Returns a maximum bitwidth of cir::IntType |
| 69 | + static unsigned maxBitwidth() { return 128; } |
| 70 | + |
| 71 | + /// Returns true if cir::IntType that represents a primitive integer type |
| 72 | + /// can be constructed from the provided bitwidth. |
| 73 | + static bool isValidPrimitiveIntBitwidth(unsigned width) { |
| 74 | + return width == 8 || width == 16 || width == 32 || width == 64; |
| 75 | + } |
| 76 | + }]; |
| 77 | + let genVerifyDecl = 1; |
| 78 | +} |
| 79 | + |
| 80 | +// Constraints |
| 81 | + |
| 82 | +// Unsigned integer type of a specific width. |
| 83 | +class UInt<int width> |
| 84 | + : Type<And<[ |
| 85 | + CPred<"::mlir::isa<::cir::IntType>($_self)">, |
| 86 | + CPred<"::mlir::cast<::cir::IntType>($_self).isUnsigned()">, |
| 87 | + CPred<"::mlir::cast<::cir::IntType>($_self).getWidth() == " # width> |
| 88 | + ]>, width # "-bit unsigned integer", "::cir::IntType">, |
| 89 | + BuildableType< |
| 90 | + "cir::IntType::get($_builder.getContext(), " |
| 91 | + # width # ", /*isSigned=*/false)"> { |
| 92 | + int bitwidth = width; |
| 93 | +} |
| 94 | + |
| 95 | +def UInt1 : UInt<1>; |
| 96 | +def UInt8 : UInt<8>; |
| 97 | +def UInt16 : UInt<16>; |
| 98 | +def UInt32 : UInt<32>; |
| 99 | +def UInt64 : UInt<64>; |
| 100 | + |
| 101 | +// Signed integer type of a specific width. |
| 102 | +class SInt<int width> |
| 103 | + : Type<And<[ |
| 104 | + CPred<"::mlir::isa<::cir::IntType>($_self)">, |
| 105 | + CPred<"::mlir::cast<::cir::IntType>($_self).isSigned()">, |
| 106 | + CPred<"::mlir::cast<::cir::IntType>($_self).getWidth() == " # width> |
| 107 | + ]>, width # "-bit signed integer", "::cir::IntType">, |
| 108 | + BuildableType< |
| 109 | + "cir::IntType::get($_builder.getContext(), " |
| 110 | + # width # ", /*isSigned=*/true)"> { |
| 111 | + int bitwidth = width; |
| 112 | +} |
| 113 | + |
| 114 | +def SInt1 : SInt<1>; |
| 115 | +def SInt8 : SInt<8>; |
| 116 | +def SInt16 : SInt<16>; |
| 117 | +def SInt32 : SInt<32>; |
| 118 | +def SInt64 : SInt<64>; |
| 119 | + |
| 120 | +def PrimitiveUInt |
| 121 | + : AnyTypeOf<[UInt8, UInt16, UInt32, UInt64], "primitive unsigned int", |
| 122 | + "::cir::IntType">; |
| 123 | + |
| 124 | +def PrimitiveSInt |
| 125 | + : AnyTypeOf<[SInt8, SInt16, SInt32, SInt64], "primitive signed int", |
| 126 | + "::cir::IntType">; |
| 127 | + |
| 128 | +def PrimitiveInt |
| 129 | + : AnyTypeOf<[UInt8, UInt16, UInt32, UInt64, SInt8, SInt16, SInt32, SInt64], |
| 130 | + "primitive int", "::cir::IntType">; |
| 131 | + |
| 132 | +#endif // MLIR_CIR_DIALECT_CIR_TYPES |
0 commit comments