|
15 | 15 | #include "mlir/IR/DialectImplementation.h"
|
16 | 16 | #include "llvm/ADT/TypeSwitch.h"
|
17 | 17 |
|
| 18 | +//===-----------------------------------------------------------------===// |
| 19 | +// IntLiteral |
| 20 | +//===-----------------------------------------------------------------===// |
| 21 | + |
| 22 | +static void printIntLiteral(mlir::AsmPrinter &p, llvm::APInt value, |
| 23 | + cir::IntTypeInterface ty); |
| 24 | +static mlir::ParseResult parseIntLiteral(mlir::AsmParser &parser, |
| 25 | + llvm::APInt &value, |
| 26 | + cir::IntTypeInterface ty); |
| 27 | +//===-----------------------------------------------------------------===// |
| 28 | +// FloatLiteral |
| 29 | +//===-----------------------------------------------------------------===// |
| 30 | + |
18 | 31 | static void printFloatLiteral(mlir::AsmPrinter &p, llvm::APFloat value,
|
19 | 32 | mlir::Type ty);
|
20 | 33 | static mlir::ParseResult
|
@@ -82,69 +95,52 @@ static void printConstPtr(AsmPrinter &p, mlir::IntegerAttr value) {
|
82 | 95 | // IntAttr definitions
|
83 | 96 | //===----------------------------------------------------------------------===//
|
84 | 97 |
|
85 |
| -Attribute IntAttr::parse(AsmParser &parser, Type odsType) { |
86 |
| - mlir::APInt apValue; |
87 |
| - |
88 |
| - if (!mlir::isa<IntType>(odsType)) |
89 |
| - return {}; |
90 |
| - auto type = mlir::cast<IntType>(odsType); |
91 |
| - |
92 |
| - // Consume the '<' symbol. |
93 |
| - if (parser.parseLess()) |
94 |
| - return {}; |
95 |
| - |
96 |
| - // Fetch arbitrary precision integer value. |
97 |
| - if (type.isSigned()) { |
98 |
| - int64_t value = 0; |
99 |
| - if (parser.parseInteger(value)) { |
100 |
| - parser.emitError(parser.getCurrentLocation(), "expected integer value"); |
101 |
| - } else { |
102 |
| - apValue = mlir::APInt(type.getWidth(), value, type.isSigned(), |
103 |
| - /*implicitTrunc=*/true); |
104 |
| - if (apValue.getSExtValue() != value) |
105 |
| - parser.emitError(parser.getCurrentLocation(), |
106 |
| - "integer value too large for the given type"); |
107 |
| - } |
| 98 | +template <typename IntT> |
| 99 | +static bool isTooLargeForType(const mlir::APInt &value, IntT expectedValue) { |
| 100 | + if constexpr (std::is_signed_v<IntT>) { |
| 101 | + return value.getSExtValue() != expectedValue; |
108 | 102 | } else {
|
109 |
| - uint64_t value = 0; |
110 |
| - if (parser.parseInteger(value)) { |
111 |
| - parser.emitError(parser.getCurrentLocation(), "expected integer value"); |
112 |
| - } else { |
113 |
| - apValue = mlir::APInt(type.getWidth(), value, type.isSigned(), |
114 |
| - /*implicitTrunc=*/true); |
115 |
| - if (apValue.getZExtValue() != value) |
116 |
| - parser.emitError(parser.getCurrentLocation(), |
117 |
| - "integer value too large for the given type"); |
118 |
| - } |
| 103 | + return value.getZExtValue() != expectedValue; |
119 | 104 | }
|
| 105 | +} |
120 | 106 |
|
121 |
| - // Consume the '>' symbol. |
122 |
| - if (parser.parseGreater()) |
123 |
| - return {}; |
| 107 | +template <typename IntT> |
| 108 | +static mlir::ParseResult parseIntLiteralImpl(mlir::AsmParser &p, |
| 109 | + llvm::APInt &value, |
| 110 | + cir::IntTypeInterface ty) { |
| 111 | + IntT ivalue; |
| 112 | + const bool isSigned = ty.isSigned(); |
| 113 | + if (p.parseInteger(ivalue)) |
| 114 | + return p.emitError(p.getCurrentLocation(), "expected integer value"); |
| 115 | + |
| 116 | + value = mlir::APInt(ty.getWidth(), ivalue, isSigned, /*implicitTrunc=*/true); |
| 117 | + if (isTooLargeForType(value, ivalue)) |
| 118 | + return p.emitError(p.getCurrentLocation(), |
| 119 | + "integer value too large for the given type"); |
124 | 120 |
|
125 |
| - return IntAttr::get(type, apValue); |
| 121 | + return success(); |
| 122 | +} |
| 123 | + |
| 124 | +mlir::ParseResult parseIntLiteral(mlir::AsmParser &parser, llvm::APInt &value, |
| 125 | + cir::IntTypeInterface ty) { |
| 126 | + if (ty.isSigned()) |
| 127 | + return parseIntLiteralImpl<int64_t>(parser, value, ty); |
| 128 | + return parseIntLiteralImpl<uint64_t>(parser, value, ty); |
126 | 129 | }
|
127 | 130 |
|
128 |
| -void IntAttr::print(AsmPrinter &printer) const { |
129 |
| - auto type = mlir::cast<IntType>(getType()); |
130 |
| - printer << '<'; |
131 |
| - if (type.isSigned()) |
132 |
| - printer << getSInt(); |
| 131 | +void printIntLiteral(mlir::AsmPrinter &p, llvm::APInt value, |
| 132 | + cir::IntTypeInterface ty) { |
| 133 | + if (ty.isSigned()) |
| 134 | + p << value.getSExtValue(); |
133 | 135 | else
|
134 |
| - printer << getUInt(); |
135 |
| - printer << '>'; |
| 136 | + p << value.getZExtValue(); |
136 | 137 | }
|
137 | 138 |
|
138 | 139 | LogicalResult IntAttr::verify(function_ref<InFlightDiagnostic()> emitError,
|
139 |
| - Type type, APInt value) { |
140 |
| - if (!mlir::isa<IntType>(type)) |
141 |
| - return emitError() << "expected 'simple.int' type"; |
142 |
| - |
143 |
| - auto intType = mlir::cast<IntType>(type); |
144 |
| - if (value.getBitWidth() != intType.getWidth()) |
| 140 | + cir::IntTypeInterface type, llvm::APInt value) { |
| 141 | + if (value.getBitWidth() != type.getWidth()) |
145 | 142 | return emitError() << "type and value bitwidth mismatch: "
|
146 |
| - << intType.getWidth() << " != " << value.getBitWidth(); |
147 |
| - |
| 143 | + << type.getWidth() << " != " << value.getBitWidth(); |
148 | 144 | return success();
|
149 | 145 | }
|
150 | 146 |
|
|
0 commit comments