CIRCT 20.0.0git
Loading...
Searching...
No Matches
MSFTAttributes.cpp
Go to the documentation of this file.
1//===- MSFTAttributes.cpp - Implement MSFT dialect attributes -------------===//
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 MSFT dialect attributes.
10//
11//===----------------------------------------------------------------------===//
12
14
15#include "mlir/IR/Builders.h"
16#include "mlir/IR/BuiltinAttributes.h"
17#include "mlir/IR/DialectImplementation.h"
18#include "llvm/ADT/TypeSwitch.h"
19
20using namespace circt;
21using namespace msft;
22
23#define GET_ATTRDEF_CLASSES
24#include "circt/Dialect/MSFT/MSFTAttributes.cpp.inc"
25
26Attribute PhysLocationAttr::parse(AsmParser &p, Type type) {
27 llvm::SMLoc loc = p.getCurrentLocation();
28 std::string subPath;
29 StringRef devTypeStr;
30 uint64_t x, y, num;
31
32 if (p.parseLess() || p.parseKeyword(&devTypeStr) || p.parseComma() ||
33 p.parseInteger(x) || p.parseComma() || p.parseInteger(y) ||
34 p.parseComma() || p.parseInteger(num) || p.parseGreater())
35 return Attribute();
36
37 std::optional<PrimitiveType> devType = symbolizePrimitiveType(devTypeStr);
38 if (!devType) {
39 p.emitError(loc, "Unknown device type '" + devTypeStr + "'");
40 return Attribute();
41 }
42 PrimitiveTypeAttr devTypeAttr =
43 PrimitiveTypeAttr::get(p.getContext(), *devType);
44 auto phy = PhysLocationAttr::get(p.getContext(), devTypeAttr, x, y, num);
45 return phy;
46}
47
48void PhysLocationAttr::print(AsmPrinter &p) const {
49 p << "<" << stringifyPrimitiveType(getPrimitiveType().getValue()) << ", "
50 << getX() << ", " << getY() << ", " << getNum() << '>';
51}
52
53Attribute PhysicalBoundsAttr::parse(AsmParser &p, Type type) {
54 uint64_t xMin, xMax, yMin, yMax;
55 if (p.parseLess() || p.parseKeyword("x") || p.parseColon() ||
56 p.parseLSquare() || p.parseInteger(xMin) || p.parseComma() ||
57 p.parseInteger(xMax) || p.parseRSquare() || p.parseComma() ||
58 p.parseKeyword("y") || p.parseColon() || p.parseLSquare() ||
59 p.parseInteger(yMin) || p.parseComma() || p.parseInteger(yMax) ||
60 p.parseRSquare() || p.parseGreater()) {
61 llvm::SMLoc loc = p.getCurrentLocation();
62 p.emitError(loc, "unable to parse PhysicalBounds");
63 return Attribute();
64 }
65
66 return PhysicalBoundsAttr::get(p.getContext(), xMin, xMax, yMin, yMax);
67}
68
69void PhysicalBoundsAttr::print(AsmPrinter &p) const {
70 p << "<";
71 p << "x: [" << getXMin() << ", " << getXMax() << "], ";
72 p << "y: [" << getYMin() << ", " << getYMax() << ']';
73 p << '>';
74}
75
76LogicalResult LocationVectorAttr::verify(
77 llvm::function_ref<mlir::InFlightDiagnostic()> emitError, TypeAttr type,
78 ArrayRef<PhysLocationAttr> locs) {
79 int64_t typeBitWidth = hw::getBitWidth(type.getValue());
80 if (typeBitWidth < 0)
81 return emitError() << "cannot compute bit width of type '" << type << "'";
82 if ((uint64_t)typeBitWidth != locs.size())
83 return emitError() << "must specify " << typeBitWidth << " locations";
84 return success();
85}
86
87LogicalResult
88circt::msft::parseOptionalRegLoc(SmallVectorImpl<PhysLocationAttr> &locs,
89 AsmParser &p) {
90 MLIRContext *ctxt = p.getContext();
91 if (!p.parseOptionalStar()) {
92 locs.push_back({});
93 return success();
94 }
95
96 PhysLocationAttr loc;
97 if (p.parseOptionalAttribute(loc).has_value()) {
98 locs.push_back(loc);
99 return success();
100 }
101
102 uint64_t x, y, n;
103 if (p.parseLess() || p.parseInteger(x) || p.parseComma() ||
104 p.parseInteger(y) || p.parseComma() || p.parseInteger(n) ||
105 p.parseGreater())
106 return failure();
107 locs.push_back(PhysLocationAttr::get(
108 ctxt, PrimitiveTypeAttr::get(ctxt, PrimitiveType::FF), x, y, n));
109 return success();
110}
111
112void circt::msft::printOptionalRegLoc(PhysLocationAttr loc, AsmPrinter &p) {
113 if (loc && loc.getPrimitiveType().getValue() == PrimitiveType::FF)
114 p << '<' << loc.getX() << ", " << loc.getY() << ", " << loc.getNum() << '>';
115 else if (loc)
116 p << loc;
117 else
118 p << "*";
119}
120
121Attribute LocationVectorAttr::parse(AsmParser &p, Type) {
122 MLIRContext *ctxt = p.getContext();
123 TypeAttr type;
124 SmallVector<PhysLocationAttr, 32> locs;
125
126 if (p.parseLess() || p.parseAttribute(type) || p.parseComma() ||
127 p.parseLSquare() || p.parseCommaSeparatedList([&]() {
128 return parseOptionalRegLoc(locs, p);
129 }) ||
130 p.parseRSquare() || p.parseGreater())
131 return {};
132
133 return LocationVectorAttr::getChecked(p.getEncodedSourceLoc(p.getNameLoc()),
134 ctxt, type, locs);
135}
136
137void LocationVectorAttr::print(AsmPrinter &p) const {
138 p << '<' << getType() << ", [";
139 llvm::interleaveComma(getLocs(), p, [&p](PhysLocationAttr loc) {
140 printOptionalRegLoc(loc, p);
141 });
142 p << "]>";
143}
144
145void MSFTDialect::registerAttributes() {
146 addAttributes<
147#define GET_ATTRDEF_LIST
148#include "circt/Dialect/MSFT/MSFTAttributes.cpp.inc"
149 >();
150}
LogicalResult parseOptionalRegLoc(SmallVectorImpl< PhysLocationAttr > &locs, AsmParser &p)
Parse and append a PhysLocAttr.
void printOptionalRegLoc(PhysLocationAttr loc, AsmPrinter &p)
Print out the above.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition msft.py:1