diff options
Diffstat (limited to 'clang/lib/CIR/Dialect/IR/CIRDialect.cpp')
-rw-r--r-- | clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 107 |
1 files changed, 104 insertions, 3 deletions
diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index dbdca1f..f98d8b6 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -12,6 +12,8 @@ #include "clang/CIR/Dialect/IR/CIRDialect.h" +#include "clang/CIR/Dialect/IR/CIRTypes.h" + #include "mlir/Support/LogicalResult.h" #include "clang/CIR/Dialect/IR/CIROpsDialect.cpp.inc" @@ -33,12 +35,72 @@ void cir::CIRDialect::initialize() { } //===----------------------------------------------------------------------===// +// ConstantOp +//===----------------------------------------------------------------------===// + +static LogicalResult checkConstantTypes(mlir::Operation *op, mlir::Type opType, + mlir::Attribute attrType) { + if (isa<cir::ConstPtrAttr>(attrType)) { + if (!mlir::isa<cir::PointerType>(opType)) + return op->emitOpError( + "pointer constant initializing a non-pointer type"); + return success(); + } + + if (mlir::isa<cir::IntAttr, cir::FPAttr>(attrType)) { + auto at = cast<TypedAttr>(attrType); + if (at.getType() != opType) { + return op->emitOpError("result type (") + << opType << ") does not match value type (" << at.getType() + << ")"; + } + return success(); + } + + assert(isa<TypedAttr>(attrType) && "What else could we be looking at here?"); + return op->emitOpError("global with type ") + << cast<TypedAttr>(attrType).getType() << " not yet supported"; +} + +LogicalResult cir::ConstantOp::verify() { + // ODS already generates checks to make sure the result type is valid. We just + // need to additionally check that the value's attribute type is consistent + // with the result type. + return checkConstantTypes(getOperation(), getType(), getValue()); +} + +OpFoldResult cir::ConstantOp::fold(FoldAdaptor /*adaptor*/) { + return getValue(); +} + +//===----------------------------------------------------------------------===// // GlobalOp //===----------------------------------------------------------------------===// -// TODO(CIR): The properties of global variables that require verification -// haven't been implemented yet. -mlir::LogicalResult cir::GlobalOp::verify() { return success(); } +static ParseResult parseConstantValue(OpAsmParser &parser, + mlir::Attribute &valueAttr) { + NamedAttrList attr; + return parser.parseAttribute(valueAttr, "value", attr); +} + +static void printConstant(OpAsmPrinter &p, Attribute value) { + p.printAttribute(value); +} + +mlir::LogicalResult cir::GlobalOp::verify() { + // Verify that the initial value, if present, is either a unit attribute or + // an attribute CIR supports. + if (getInitialValue().has_value()) { + if (checkConstantTypes(getOperation(), getSymType(), *getInitialValue()) + .failed()) + return failure(); + } + + // TODO(CIR): Many other checks for properties that haven't been upstreamed + // yet. + + return success(); +} void cir::GlobalOp::build(OpBuilder &odsBuilder, OperationState &odsState, llvm::StringRef sym_name, mlir::Type sym_type) { @@ -48,6 +110,45 @@ void cir::GlobalOp::build(OpBuilder &odsBuilder, OperationState &odsState, mlir::TypeAttr::get(sym_type)); } +static void printGlobalOpTypeAndInitialValue(OpAsmPrinter &p, cir::GlobalOp op, + TypeAttr type, + Attribute initAttr) { + if (!op.isDeclaration()) { + p << "= "; + // This also prints the type... + if (initAttr) + printConstant(p, initAttr); + } else { + p << ": " << type; + } +} + +static ParseResult +parseGlobalOpTypeAndInitialValue(OpAsmParser &parser, TypeAttr &typeAttr, + Attribute &initialValueAttr) { + mlir::Type opTy; + if (parser.parseOptionalEqual().failed()) { + // Absence of equal means a declaration, so we need to parse the type. + // cir.global @a : !cir.int<s, 32> + if (parser.parseColonType(opTy)) + return failure(); + } else { + // Parse constant with initializer, examples: + // cir.global @y = #cir.fp<1.250000e+00> : !cir.double + // cir.global @rgb = #cir.const_array<[...] : !cir.array<i8 x 3>> + if (parseConstantValue(parser, initialValueAttr).failed()) + return failure(); + + assert(mlir::isa<mlir::TypedAttr>(initialValueAttr) && + "Non-typed attrs shouldn't appear here."); + auto typedAttr = mlir::cast<mlir::TypedAttr>(initialValueAttr); + opTy = typedAttr.getType(); + } + + typeAttr = TypeAttr::get(opTy); + return success(); +} + //===----------------------------------------------------------------------===// // FuncOp //===----------------------------------------------------------------------===// |