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