CIRCT  20.0.0git
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 
20 using namespace circt;
21 using namespace msft;
22 
23 #define GET_ATTRDEF_CLASSES
24 #include "circt/Dialect/MSFT/MSFTAttributes.cpp.inc"
25 
26 Attribute 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 
48 void PhysLocationAttr::print(AsmPrinter &p) const {
49  p << "<" << stringifyPrimitiveType(getPrimitiveType().getValue()) << ", "
50  << getX() << ", " << getY() << ", " << getNum() << '>';
51 }
52 
53 Attribute 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 
69 void PhysicalBoundsAttr::print(AsmPrinter &p) const {
70  p << "<";
71  p << "x: [" << getXMin() << ", " << getXMax() << "], ";
72  p << "y: [" << getYMin() << ", " << getYMax() << ']';
73  p << '>';
74 }
75 
76 LogicalResult 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 
87 LogicalResult
88 circt::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 
112 void 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 
121 Attribute 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 
137 void 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 
145 void MSFTDialect::registerAttributes() {
146  addAttributes<
147 #define GET_ATTRDEF_LIST
148 #include "circt/Dialect/MSFT/MSFTAttributes.cpp.inc"
149  >();
150 }
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
Definition: CalyxOps.cpp:55
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21
Definition: msft.py:1