aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CIR/Dialect/IR/CIRDialect.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CIR/Dialect/IR/CIRDialect.cpp')
-rw-r--r--clang/lib/CIR/Dialect/IR/CIRDialect.cpp107
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
//===----------------------------------------------------------------------===//