xref: /llvm-project/clang/lib/CIR/Dialect/IR/CIRDialect.cpp (revision 8e329593313bb792592529ee825a52683108df99)
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