12#include "mlir/IR/Builders.h"
13#include "mlir/IR/DialectImplementation.h"
14#include "llvm/ADT/TypeSwitch.h"
29 for (
auto element : set)
34template <
typename K,
typename V>
39 for (
auto [key, value] : map)
40 hash ^= (key ^ value);
50SetAttr::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
51 rtg::SetType type,
const DenseSet<TypedAttr> *elements) {
57 if (!llvm::all_of(*elements, [&](
auto element) {
58 return element.getType() == type.getElementType();
60 return emitError() <<
"all elements must be of the set element type "
61 << type.getElementType();
67Attribute SetAttr::parse(AsmParser &odsParser, Type odsType) {
68 DenseSet<TypedAttr> elements;
70 if (odsParser.parseCommaSeparatedList(mlir::AsmParser::Delimiter::LessGreater,
73 if (odsParser.parseAttribute(element))
75 elements.insert(element);
76 elementType = element.getType();
81 auto setType = llvm::dyn_cast_or_null<SetType>(odsType);
82 if (odsType && !setType) {
83 odsParser.emitError(odsParser.getNameLoc())
84 <<
"type must be a an '!rtg.set' type";
88 if (!setType && elements.empty()) {
89 odsParser.emitError(odsParser.getNameLoc())
90 <<
"type must be explicitly provided: cannot infer set element type "
95 if (!setType && !elements.empty())
98 return SetAttr::getChecked(
99 odsParser.getEncodedSourceLoc(odsParser.getNameLoc()),
100 odsParser.getContext(), setType, &elements);
103void SetAttr::print(AsmPrinter &odsPrinter)
const {
106 SmallVector<std::string> sortedElements;
107 for (
auto element : *getElements()) {
108 std::string &elementStr = sortedElements.emplace_back();
109 llvm::raw_string_ostream elementOS(elementStr);
110 element.print(elementOS);
112 llvm::sort(sortedElements);
113 llvm::interleaveComma(sortedElements, odsPrinter);
122MapAttr::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
124 const DenseMap<TypedAttr, TypedAttr> *entries) {
127 if (!llvm::all_of(*entries, [&](
auto entry) {
128 return entry.first.getType() == type.getKeyType() &&
129 entry.second.getType() == type.getValueType();
131 return emitError() <<
"all keys must be of type " << type.getKeyType()
132 <<
" and all values must be of type "
133 << type.getValueType();
139Attribute MapAttr::parse(AsmParser &odsParser, Type odsType) {
140 DenseMap<TypedAttr, TypedAttr> entries;
141 Type keyType, valueType;
142 if (odsParser.parseCommaSeparatedList(
143 mlir::AsmParser::Delimiter::LessGreater, [&]() {
144 TypedAttr key, value;
145 if (odsParser.parseAttribute(key) || odsParser.parseArrow() ||
146 odsParser.parseAttribute(value))
148 entries.insert({key, value});
149 keyType = key.getType();
150 valueType = value.getType();
155 auto mapType = llvm::dyn_cast_or_null<MapType>(odsType);
156 if (odsType && !mapType) {
157 odsParser.emitError(odsParser.getNameLoc())
158 <<
"type must be an '!rtg.map' type";
162 if (!mapType && entries.empty()) {
163 odsParser.emitError(odsParser.getNameLoc())
164 <<
"type must be explicitly provided: cannot infer map key and value "
165 "types from empty map";
169 if (!mapType && !entries.empty())
170 mapType = MapType::get(keyType, valueType);
172 return MapAttr::getChecked(
173 odsParser.getEncodedSourceLoc(odsParser.getNameLoc()),
174 odsParser.getContext(), mapType, &entries);
177void MapAttr::print(AsmPrinter &odsPrinter)
const {
180 SmallVector<std::pair<std::string, std::string>> sortedEntries;
181 for (
auto [key, value] : *getEntries()) {
182 std::string keyStr, valueStr;
183 llvm::raw_string_ostream keyOS(keyStr);
184 llvm::raw_string_ostream valueOS(valueStr);
186 value.print(valueOS);
187 sortedEntries.emplace_back(std::move(keyStr), std::move(valueStr));
189 llvm::sort(sortedEntries);
190 llvm::interleaveComma(sortedEntries, odsPrinter, [&](
auto &entry) {
191 odsPrinter << entry.first <<
" -> " << entry.second;
200Type TupleAttr::getType()
const {
201 SmallVector<Type> elementTypes(llvm::map_range(
202 getElements(), [](
auto element) {
return element.getType(); }));
203 return TupleType::get(getContext(), elementTypes);
225 return (
value.getBitWidth() == key.getBitWidth() &&
value == key);
244Type ImmediateAttr::getType()
const {
245 return ImmediateType::get(getContext(), getValue().
getBitWidth());
248APInt ImmediateAttr::getValue()
const {
return getImpl()->value; }
250Attribute ImmediateAttr::parse(AsmParser &odsParser, Type odsType) {
251 llvm::SMLoc loc = odsParser.getCurrentLocation();
256 if (odsParser.parseLess() || odsParser.parseInteger(width) ||
257 odsParser.parseComma() || odsParser.parseInteger(val) ||
258 odsParser.parseGreater())
262 if (
auto immTy = llvm::dyn_cast_or_null<ImmediateType>(odsType)) {
263 if (immTy.getWidth() != width) {
264 odsParser.emitError(loc) <<
"explicit immediate type bit-width does not "
265 "match attribute bit-width, "
266 << immTy.getWidth() <<
" vs " << width;
271 if (width > val.getBitWidth()) {
275 val = val.sext(width);
276 }
else if (width < val.getBitWidth()) {
279 unsigned neededBits =
280 val.isNegative() ? val.getSignificantBits() : val.getActiveBits();
281 if (width < neededBits) {
282 odsParser.emitError(loc)
283 <<
"integer value out-of-range for bit-width " << width;
286 val = val.trunc(width);
289 return ImmediateAttr::get(odsParser.getContext(), val);
292void ImmediateAttr::print(AsmPrinter &odsPrinter)
const {
293 odsPrinter <<
"<" << getValue().getBitWidth() <<
", " << getValue() <<
">";
296Type VirtualRegisterConfigAttr::getType()
const {
297 return getAllowedRegs()[0].getType();
300LogicalResult VirtualRegisterConfigAttr::verify(
301 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
302 ArrayRef<rtg::RegisterAttrInterface> allowedRegs) {
303 if (allowedRegs.empty())
304 return emitError() <<
"must have at least one allowed register";
306 if (!llvm::all_of(allowedRegs, [&](
auto reg) {
307 return reg.getType() == allowedRegs[0].getType();
309 return emitError() <<
"all allowed registers must be of the same type";
319Type LabelAttr::getType()
const {
return LabelType::get(getContext()); }
325void RTGDialect::registerAttributes() {
327#define GET_ATTRDEF_LIST
328#include "circt/Dialect/RTG/IR/RTGAttributes.cpp.inc"
332#define GET_ATTRDEF_CLASSES
333#include "circt/Dialect/RTG/IR/RTGAttributes.cpp.inc"
int64_t getBitWidth(mlir::Type type)
Return the hardware bit width of a type.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
llvm::hash_code hash_value(const DenseSet< T > &set)
reg(value, clock, reset=None, reset_value=None, name=None, sym_name=None)