1c695a325SDavid Olsen //===- CIRAttrs.cpp - MLIR CIR Attributes ---------------------------------===// 2c695a325SDavid Olsen // 3c695a325SDavid Olsen // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4c695a325SDavid Olsen // See https://llvm.org/LICENSE.txt for license information. 5c695a325SDavid Olsen // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6c695a325SDavid Olsen // 7c695a325SDavid Olsen //===----------------------------------------------------------------------===// 8c695a325SDavid Olsen // 9c695a325SDavid Olsen // This file defines the attributes in the CIR dialect. 10c695a325SDavid Olsen // 11c695a325SDavid Olsen //===----------------------------------------------------------------------===// 12c695a325SDavid Olsen 13c695a325SDavid Olsen #include "clang/CIR/Dialect/IR/CIRDialect.h" 14c695a325SDavid Olsen 15*8e329593SDavid Olsen #include "mlir/IR/DialectImplementation.h" 16*8e329593SDavid Olsen #include "llvm/ADT/TypeSwitch.h" 17*8e329593SDavid Olsen 18*8e329593SDavid Olsen static void printFloatLiteral(mlir::AsmPrinter &p, llvm::APFloat value, 19*8e329593SDavid Olsen mlir::Type ty); 20*8e329593SDavid Olsen static mlir::ParseResult 21*8e329593SDavid Olsen parseFloatLiteral(mlir::AsmParser &parser, 22*8e329593SDavid Olsen mlir::FailureOr<llvm::APFloat> &value, 23*8e329593SDavid Olsen cir::CIRFPTypeInterface fpType); 24*8e329593SDavid Olsen 25*8e329593SDavid Olsen static mlir::ParseResult parseConstPtr(mlir::AsmParser &parser, 26*8e329593SDavid Olsen mlir::IntegerAttr &value); 27*8e329593SDavid Olsen 28*8e329593SDavid Olsen static void printConstPtr(mlir::AsmPrinter &p, mlir::IntegerAttr value); 29*8e329593SDavid Olsen 30*8e329593SDavid Olsen #define GET_ATTRDEF_CLASSES 31*8e329593SDavid Olsen #include "clang/CIR/Dialect/IR/CIROpsAttributes.cpp.inc" 32*8e329593SDavid Olsen 33c695a325SDavid Olsen using namespace mlir; 34c72389d4SShoaib Meenai using namespace cir; 35c695a325SDavid Olsen 36c695a325SDavid Olsen //===----------------------------------------------------------------------===// 37c695a325SDavid Olsen // General CIR parsing / printing 38c695a325SDavid Olsen //===----------------------------------------------------------------------===// 39c695a325SDavid Olsen 40c695a325SDavid Olsen Attribute CIRDialect::parseAttribute(DialectAsmParser &parser, 41c695a325SDavid Olsen Type type) const { 42*8e329593SDavid Olsen llvm::SMLoc typeLoc = parser.getCurrentLocation(); 43*8e329593SDavid Olsen llvm::StringRef mnemonic; 44*8e329593SDavid Olsen Attribute genAttr; 45*8e329593SDavid Olsen OptionalParseResult parseResult = 46*8e329593SDavid Olsen generatedAttributeParser(parser, &mnemonic, type, genAttr); 47*8e329593SDavid Olsen if (parseResult.has_value()) 48*8e329593SDavid Olsen return genAttr; 49*8e329593SDavid Olsen parser.emitError(typeLoc, "unknown attribute in CIR dialect"); 50*8e329593SDavid Olsen return Attribute(); 51c695a325SDavid Olsen } 52c695a325SDavid Olsen 53c695a325SDavid Olsen void CIRDialect::printAttribute(Attribute attr, DialectAsmPrinter &os) const { 54*8e329593SDavid Olsen if (failed(generatedAttributePrinter(attr, os))) 55*8e329593SDavid Olsen llvm_unreachable("unexpected CIR type kind"); 56*8e329593SDavid Olsen } 57*8e329593SDavid Olsen 58*8e329593SDavid Olsen //===----------------------------------------------------------------------===// 59*8e329593SDavid Olsen // ConstPtrAttr definitions 60*8e329593SDavid Olsen //===----------------------------------------------------------------------===// 61*8e329593SDavid Olsen 62*8e329593SDavid Olsen // TODO(CIR): Consider encoding the null value differently and use conditional 63*8e329593SDavid Olsen // assembly format instead of custom parsing/printing. 64*8e329593SDavid Olsen static ParseResult parseConstPtr(AsmParser &parser, mlir::IntegerAttr &value) { 65*8e329593SDavid Olsen 66*8e329593SDavid Olsen if (parser.parseOptionalKeyword("null").succeeded()) { 67*8e329593SDavid Olsen value = mlir::IntegerAttr::get( 68*8e329593SDavid Olsen mlir::IntegerType::get(parser.getContext(), 64), 0); 69*8e329593SDavid Olsen return success(); 70*8e329593SDavid Olsen } 71*8e329593SDavid Olsen 72*8e329593SDavid Olsen return parser.parseAttribute(value); 73*8e329593SDavid Olsen } 74*8e329593SDavid Olsen 75*8e329593SDavid Olsen static void printConstPtr(AsmPrinter &p, mlir::IntegerAttr value) { 76*8e329593SDavid Olsen if (!value.getInt()) 77*8e329593SDavid Olsen p << "null"; 78*8e329593SDavid Olsen else 79*8e329593SDavid Olsen p << value; 80*8e329593SDavid Olsen } 81*8e329593SDavid Olsen 82*8e329593SDavid Olsen //===----------------------------------------------------------------------===// 83*8e329593SDavid Olsen // IntAttr definitions 84*8e329593SDavid Olsen //===----------------------------------------------------------------------===// 85*8e329593SDavid Olsen 86*8e329593SDavid Olsen Attribute IntAttr::parse(AsmParser &parser, Type odsType) { 87*8e329593SDavid Olsen mlir::APInt apValue; 88*8e329593SDavid Olsen 89*8e329593SDavid Olsen if (!mlir::isa<IntType>(odsType)) 90*8e329593SDavid Olsen return {}; 91*8e329593SDavid Olsen auto type = mlir::cast<IntType>(odsType); 92*8e329593SDavid Olsen 93*8e329593SDavid Olsen // Consume the '<' symbol. 94*8e329593SDavid Olsen if (parser.parseLess()) 95*8e329593SDavid Olsen return {}; 96*8e329593SDavid Olsen 97*8e329593SDavid Olsen // Fetch arbitrary precision integer value. 98*8e329593SDavid Olsen if (type.isSigned()) { 99*8e329593SDavid Olsen int64_t value = 0; 100*8e329593SDavid Olsen if (parser.parseInteger(value)) { 101*8e329593SDavid Olsen parser.emitError(parser.getCurrentLocation(), "expected integer value"); 102*8e329593SDavid Olsen } else { 103*8e329593SDavid Olsen apValue = mlir::APInt(type.getWidth(), value, type.isSigned(), 104*8e329593SDavid Olsen /*implicitTrunc=*/true); 105*8e329593SDavid Olsen if (apValue.getSExtValue() != value) 106*8e329593SDavid Olsen parser.emitError(parser.getCurrentLocation(), 107*8e329593SDavid Olsen "integer value too large for the given type"); 108*8e329593SDavid Olsen } 109*8e329593SDavid Olsen } else { 110*8e329593SDavid Olsen uint64_t value = 0; 111*8e329593SDavid Olsen if (parser.parseInteger(value)) { 112*8e329593SDavid Olsen parser.emitError(parser.getCurrentLocation(), "expected integer value"); 113*8e329593SDavid Olsen } else { 114*8e329593SDavid Olsen apValue = mlir::APInt(type.getWidth(), value, type.isSigned(), 115*8e329593SDavid Olsen /*implicitTrunc=*/true); 116*8e329593SDavid Olsen if (apValue.getZExtValue() != value) 117*8e329593SDavid Olsen parser.emitError(parser.getCurrentLocation(), 118*8e329593SDavid Olsen "integer value too large for the given type"); 119*8e329593SDavid Olsen } 120*8e329593SDavid Olsen } 121*8e329593SDavid Olsen 122*8e329593SDavid Olsen // Consume the '>' symbol. 123*8e329593SDavid Olsen if (parser.parseGreater()) 124*8e329593SDavid Olsen return {}; 125*8e329593SDavid Olsen 126*8e329593SDavid Olsen return IntAttr::get(type, apValue); 127*8e329593SDavid Olsen } 128*8e329593SDavid Olsen 129*8e329593SDavid Olsen void IntAttr::print(AsmPrinter &printer) const { 130*8e329593SDavid Olsen auto type = mlir::cast<IntType>(getType()); 131*8e329593SDavid Olsen printer << '<'; 132*8e329593SDavid Olsen if (type.isSigned()) 133*8e329593SDavid Olsen printer << getSInt(); 134*8e329593SDavid Olsen else 135*8e329593SDavid Olsen printer << getUInt(); 136*8e329593SDavid Olsen printer << '>'; 137*8e329593SDavid Olsen } 138*8e329593SDavid Olsen 139*8e329593SDavid Olsen LogicalResult IntAttr::verify(function_ref<InFlightDiagnostic()> emitError, 140*8e329593SDavid Olsen Type type, APInt value) { 141*8e329593SDavid Olsen if (!mlir::isa<IntType>(type)) { 142*8e329593SDavid Olsen emitError() << "expected 'simple.int' type"; 143*8e329593SDavid Olsen return failure(); 144*8e329593SDavid Olsen } 145*8e329593SDavid Olsen 146*8e329593SDavid Olsen auto intType = mlir::cast<IntType>(type); 147*8e329593SDavid Olsen if (value.getBitWidth() != intType.getWidth()) { 148*8e329593SDavid Olsen emitError() << "type and value bitwidth mismatch: " << intType.getWidth() 149*8e329593SDavid Olsen << " != " << value.getBitWidth(); 150*8e329593SDavid Olsen return failure(); 151*8e329593SDavid Olsen } 152*8e329593SDavid Olsen 153*8e329593SDavid Olsen return success(); 154*8e329593SDavid Olsen } 155*8e329593SDavid Olsen 156*8e329593SDavid Olsen //===----------------------------------------------------------------------===// 157*8e329593SDavid Olsen // FPAttr definitions 158*8e329593SDavid Olsen //===----------------------------------------------------------------------===// 159*8e329593SDavid Olsen 160*8e329593SDavid Olsen static void printFloatLiteral(AsmPrinter &p, APFloat value, Type ty) { 161*8e329593SDavid Olsen p << value; 162*8e329593SDavid Olsen } 163*8e329593SDavid Olsen 164*8e329593SDavid Olsen static ParseResult parseFloatLiteral(AsmParser &parser, 165*8e329593SDavid Olsen FailureOr<APFloat> &value, 166*8e329593SDavid Olsen CIRFPTypeInterface fpType) { 167*8e329593SDavid Olsen 168*8e329593SDavid Olsen APFloat parsedValue(0.0); 169*8e329593SDavid Olsen if (parser.parseFloat(fpType.getFloatSemantics(), parsedValue)) 170*8e329593SDavid Olsen return failure(); 171*8e329593SDavid Olsen 172*8e329593SDavid Olsen value.emplace(parsedValue); 173*8e329593SDavid Olsen return success(); 174*8e329593SDavid Olsen } 175*8e329593SDavid Olsen 176*8e329593SDavid Olsen FPAttr FPAttr::getZero(Type type) { 177*8e329593SDavid Olsen return get(type, 178*8e329593SDavid Olsen APFloat::getZero( 179*8e329593SDavid Olsen mlir::cast<CIRFPTypeInterface>(type).getFloatSemantics())); 180*8e329593SDavid Olsen } 181*8e329593SDavid Olsen 182*8e329593SDavid Olsen LogicalResult FPAttr::verify(function_ref<InFlightDiagnostic()> emitError, 183*8e329593SDavid Olsen CIRFPTypeInterface fpType, APFloat value) { 184*8e329593SDavid Olsen if (APFloat::SemanticsToEnum(fpType.getFloatSemantics()) != 185*8e329593SDavid Olsen APFloat::SemanticsToEnum(value.getSemantics())) { 186*8e329593SDavid Olsen emitError() << "floating-point semantics mismatch"; 187*8e329593SDavid Olsen return failure(); 188*8e329593SDavid Olsen } 189*8e329593SDavid Olsen 190*8e329593SDavid Olsen return success(); 191c695a325SDavid Olsen } 192c695a325SDavid Olsen 193c695a325SDavid Olsen //===----------------------------------------------------------------------===// 194c695a325SDavid Olsen // CIR Dialect 195c695a325SDavid Olsen //===----------------------------------------------------------------------===// 196c695a325SDavid Olsen 197c695a325SDavid Olsen void CIRDialect::registerAttributes() { 198*8e329593SDavid Olsen addAttributes< 199*8e329593SDavid Olsen #define GET_ATTRDEF_LIST 200*8e329593SDavid Olsen #include "clang/CIR/Dialect/IR/CIROpsAttributes.cpp.inc" 201*8e329593SDavid Olsen >(); 202c695a325SDavid Olsen } 203