110661ba2SNathan Lanza //===- CIRDialect.cpp - MLIR CIR ops implementation -----------------------===// 210661ba2SNathan Lanza // 310661ba2SNathan Lanza // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 410661ba2SNathan Lanza // See https://llvm.org/LICENSE.txt for license information. 510661ba2SNathan Lanza // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 610661ba2SNathan Lanza // 710661ba2SNathan Lanza //===----------------------------------------------------------------------===// 810661ba2SNathan Lanza // 910661ba2SNathan Lanza // This file implements the CIR dialect and its operations. 1010661ba2SNathan Lanza // 1110661ba2SNathan Lanza //===----------------------------------------------------------------------===// 1210661ba2SNathan Lanza 13c695a325SDavid Olsen #include "clang/CIR/Dialect/IR/CIRDialect.h" 14c695a325SDavid Olsen 15*8e329593SDavid Olsen #include "clang/CIR/Dialect/IR/CIRTypes.h" 16*8e329593SDavid Olsen 17c695a325SDavid Olsen #include "mlir/Support/LogicalResult.h" 18c695a325SDavid Olsen 19c695a325SDavid Olsen #include "clang/CIR/Dialect/IR/CIROpsDialect.cpp.inc" 20c695a325SDavid Olsen 21c695a325SDavid Olsen using namespace mlir; 22c72389d4SShoaib Meenai using namespace cir; 23c695a325SDavid Olsen 24c695a325SDavid Olsen //===----------------------------------------------------------------------===// 25c695a325SDavid Olsen // CIR Dialect 26c695a325SDavid Olsen //===----------------------------------------------------------------------===// 27c695a325SDavid Olsen 28c72389d4SShoaib Meenai void cir::CIRDialect::initialize() { 29c695a325SDavid Olsen registerTypes(); 30c695a325SDavid Olsen registerAttributes(); 31c695a325SDavid Olsen addOperations< 32c695a325SDavid Olsen #define GET_OP_LIST 33c695a325SDavid Olsen #include "clang/CIR/Dialect/IR/CIROps.cpp.inc" 34c695a325SDavid Olsen >(); 35c695a325SDavid Olsen } 36c695a325SDavid Olsen 37c695a325SDavid Olsen //===----------------------------------------------------------------------===// 38*8e329593SDavid Olsen // ConstantOp 39*8e329593SDavid Olsen //===----------------------------------------------------------------------===// 40*8e329593SDavid Olsen 41*8e329593SDavid Olsen static LogicalResult checkConstantTypes(mlir::Operation *op, mlir::Type opType, 42*8e329593SDavid Olsen mlir::Attribute attrType) { 43*8e329593SDavid Olsen if (isa<cir::ConstPtrAttr>(attrType)) { 44*8e329593SDavid Olsen if (!mlir::isa<cir::PointerType>(opType)) 45*8e329593SDavid Olsen return op->emitOpError( 46*8e329593SDavid Olsen "pointer constant initializing a non-pointer type"); 47*8e329593SDavid Olsen return success(); 48*8e329593SDavid Olsen } 49*8e329593SDavid Olsen 50*8e329593SDavid Olsen if (mlir::isa<cir::IntAttr, cir::FPAttr>(attrType)) { 51*8e329593SDavid Olsen auto at = cast<TypedAttr>(attrType); 52*8e329593SDavid Olsen if (at.getType() != opType) { 53*8e329593SDavid Olsen return op->emitOpError("result type (") 54*8e329593SDavid Olsen << opType << ") does not match value type (" << at.getType() 55*8e329593SDavid Olsen << ")"; 56*8e329593SDavid Olsen } 57*8e329593SDavid Olsen return success(); 58*8e329593SDavid Olsen } 59*8e329593SDavid Olsen 60*8e329593SDavid Olsen assert(isa<TypedAttr>(attrType) && "What else could we be looking at here?"); 61*8e329593SDavid Olsen return op->emitOpError("global with type ") 62*8e329593SDavid Olsen << cast<TypedAttr>(attrType).getType() << " not yet supported"; 63*8e329593SDavid Olsen } 64*8e329593SDavid Olsen 65*8e329593SDavid Olsen LogicalResult cir::ConstantOp::verify() { 66*8e329593SDavid Olsen // ODS already generates checks to make sure the result type is valid. We just 67*8e329593SDavid Olsen // need to additionally check that the value's attribute type is consistent 68*8e329593SDavid Olsen // with the result type. 69*8e329593SDavid Olsen return checkConstantTypes(getOperation(), getType(), getValue()); 70*8e329593SDavid Olsen } 71*8e329593SDavid Olsen 72*8e329593SDavid Olsen OpFoldResult cir::ConstantOp::fold(FoldAdaptor /*adaptor*/) { 73*8e329593SDavid Olsen return getValue(); 74*8e329593SDavid Olsen } 75*8e329593SDavid Olsen 76*8e329593SDavid Olsen //===----------------------------------------------------------------------===// 77a43b2e13SDavid Olsen // GlobalOp 78a43b2e13SDavid Olsen //===----------------------------------------------------------------------===// 79a43b2e13SDavid Olsen 80*8e329593SDavid Olsen static ParseResult parseConstantValue(OpAsmParser &parser, 81*8e329593SDavid Olsen mlir::Attribute &valueAttr) { 82*8e329593SDavid Olsen NamedAttrList attr; 83*8e329593SDavid Olsen return parser.parseAttribute(valueAttr, "value", attr); 84*8e329593SDavid Olsen } 85*8e329593SDavid Olsen 86*8e329593SDavid Olsen static void printConstant(OpAsmPrinter &p, Attribute value) { 87*8e329593SDavid Olsen p.printAttribute(value); 88*8e329593SDavid Olsen } 89*8e329593SDavid Olsen 90*8e329593SDavid Olsen mlir::LogicalResult cir::GlobalOp::verify() { 91*8e329593SDavid Olsen // Verify that the initial value, if present, is either a unit attribute or 92*8e329593SDavid Olsen // an attribute CIR supports. 93*8e329593SDavid Olsen if (getInitialValue().has_value()) { 94*8e329593SDavid Olsen if (checkConstantTypes(getOperation(), getSymType(), *getInitialValue()) 95*8e329593SDavid Olsen .failed()) 96*8e329593SDavid Olsen return failure(); 97*8e329593SDavid Olsen } 98*8e329593SDavid Olsen 99*8e329593SDavid Olsen // TODO(CIR): Many other checks for properties that haven't been upstreamed 100*8e329593SDavid Olsen // yet. 101*8e329593SDavid Olsen 102*8e329593SDavid Olsen return success(); 103*8e329593SDavid Olsen } 104a43b2e13SDavid Olsen 105a43b2e13SDavid Olsen void cir::GlobalOp::build(OpBuilder &odsBuilder, OperationState &odsState, 106a43b2e13SDavid Olsen llvm::StringRef sym_name, mlir::Type sym_type) { 107a43b2e13SDavid Olsen odsState.addAttribute(getSymNameAttrName(odsState.name), 108a43b2e13SDavid Olsen odsBuilder.getStringAttr(sym_name)); 109a43b2e13SDavid Olsen odsState.addAttribute(getSymTypeAttrName(odsState.name), 110a43b2e13SDavid Olsen mlir::TypeAttr::get(sym_type)); 111a43b2e13SDavid Olsen } 112a43b2e13SDavid Olsen 113*8e329593SDavid Olsen static void printGlobalOpTypeAndInitialValue(OpAsmPrinter &p, cir::GlobalOp op, 114*8e329593SDavid Olsen TypeAttr type, 115*8e329593SDavid Olsen Attribute initAttr) { 116*8e329593SDavid Olsen if (!op.isDeclaration()) { 117*8e329593SDavid Olsen p << "= "; 118*8e329593SDavid Olsen // This also prints the type... 119*8e329593SDavid Olsen if (initAttr) 120*8e329593SDavid Olsen printConstant(p, initAttr); 121*8e329593SDavid Olsen } else { 122*8e329593SDavid Olsen p << ": " << type; 123*8e329593SDavid Olsen } 124*8e329593SDavid Olsen } 125*8e329593SDavid Olsen 126*8e329593SDavid Olsen static ParseResult 127*8e329593SDavid Olsen parseGlobalOpTypeAndInitialValue(OpAsmParser &parser, TypeAttr &typeAttr, 128*8e329593SDavid Olsen Attribute &initialValueAttr) { 129*8e329593SDavid Olsen mlir::Type opTy; 130*8e329593SDavid Olsen if (parser.parseOptionalEqual().failed()) { 131*8e329593SDavid Olsen // Absence of equal means a declaration, so we need to parse the type. 132*8e329593SDavid Olsen // cir.global @a : !cir.int<s, 32> 133*8e329593SDavid Olsen if (parser.parseColonType(opTy)) 134*8e329593SDavid Olsen return failure(); 135*8e329593SDavid Olsen } else { 136*8e329593SDavid Olsen // Parse constant with initializer, examples: 137*8e329593SDavid Olsen // cir.global @y = #cir.fp<1.250000e+00> : !cir.double 138*8e329593SDavid Olsen // cir.global @rgb = #cir.const_array<[...] : !cir.array<i8 x 3>> 139*8e329593SDavid Olsen if (parseConstantValue(parser, initialValueAttr).failed()) 140*8e329593SDavid Olsen return failure(); 141*8e329593SDavid Olsen 142*8e329593SDavid Olsen assert(mlir::isa<mlir::TypedAttr>(initialValueAttr) && 143*8e329593SDavid Olsen "Non-typed attrs shouldn't appear here."); 144*8e329593SDavid Olsen auto typedAttr = mlir::cast<mlir::TypedAttr>(initialValueAttr); 145*8e329593SDavid Olsen opTy = typedAttr.getType(); 146*8e329593SDavid Olsen } 147*8e329593SDavid Olsen 148*8e329593SDavid Olsen typeAttr = TypeAttr::get(opTy); 149*8e329593SDavid Olsen return success(); 150*8e329593SDavid Olsen } 151*8e329593SDavid Olsen 152a43b2e13SDavid Olsen //===----------------------------------------------------------------------===// 153c695a325SDavid Olsen // FuncOp 154c695a325SDavid Olsen //===----------------------------------------------------------------------===// 155c695a325SDavid Olsen 156c72389d4SShoaib Meenai void cir::FuncOp::build(OpBuilder &builder, OperationState &result, 157c695a325SDavid Olsen StringRef name) { 158c695a325SDavid Olsen result.addAttribute(SymbolTable::getSymbolAttrName(), 159c695a325SDavid Olsen builder.getStringAttr(name)); 160c695a325SDavid Olsen } 161c695a325SDavid Olsen 162c695a325SDavid Olsen ParseResult cir::FuncOp::parse(OpAsmParser &parser, OperationState &state) { 163c695a325SDavid Olsen StringAttr nameAttr; 164c695a325SDavid Olsen if (parser.parseSymbolName(nameAttr, SymbolTable::getSymbolAttrName(), 165c695a325SDavid Olsen state.attributes)) 166c695a325SDavid Olsen return failure(); 167c695a325SDavid Olsen return success(); 168c695a325SDavid Olsen } 169c695a325SDavid Olsen 170c695a325SDavid Olsen void cir::FuncOp::print(OpAsmPrinter &p) { 171c695a325SDavid Olsen p << ' '; 172c695a325SDavid Olsen // For now the only property a function has is its name 173c695a325SDavid Olsen p.printSymbolName(getSymName()); 174c695a325SDavid Olsen } 175c695a325SDavid Olsen 176a43b2e13SDavid Olsen // TODO(CIR): The properties of functions that require verification haven't 177a43b2e13SDavid Olsen // been implemented yet. 178c72389d4SShoaib Meenai mlir::LogicalResult cir::FuncOp::verify() { return success(); } 179c695a325SDavid Olsen 180c695a325SDavid Olsen //===----------------------------------------------------------------------===// 181c695a325SDavid Olsen // TableGen'd op method definitions 182c695a325SDavid Olsen //===----------------------------------------------------------------------===// 183c695a325SDavid Olsen 184c695a325SDavid Olsen #define GET_OP_CLASSES 185c695a325SDavid Olsen #include "clang/CIR/Dialect/IR/CIROps.cpp.inc" 186