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);
210Type VirtualRegisterConfigAttr::getType()
const {
211 return getAllowedRegs()[0].getType();
214LogicalResult VirtualRegisterConfigAttr::verify(
215 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
216 ArrayRef<rtg::RegisterAttrInterface> allowedRegs) {
217 if (allowedRegs.empty())
218 return emitError() <<
"must have at least one allowed register";
220 if (!llvm::all_of(allowedRegs, [&](
auto reg) {
221 return reg.getType() == allowedRegs[0].getType();
223 return emitError() <<
"all allowed registers must be of the same type";
233Type LabelAttr::getType()
const {
return LabelType::get(getContext()); }
239void RTGDialect::registerAttributes() {
241#define GET_ATTRDEF_LIST
242#include "circt/Dialect/RTG/IR/RTGAttributes.cpp.inc"
246#define GET_ATTRDEF_CLASSES
247#include "circt/Dialect/RTG/IR/RTGAttributes.cpp.inc"
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)