11#include "mlir/IR/Builders.h"
12#include "mlir/IR/DialectImplementation.h"
13#include "llvm/ADT/TypeSwitch.h"
28 for (
auto element : set)
39SetAttr::verify(llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
40 rtg::SetType type,
const DenseSet<TypedAttr> *elements) {
46 if (!llvm::all_of(*elements, [&](
auto element) {
47 return element.getType() == type.getElementType();
49 return emitError() <<
"all elements must be of the set element type "
50 << type.getElementType();
56Attribute SetAttr::parse(AsmParser &odsParser, Type odsType) {
57 DenseSet<TypedAttr> elements;
59 if (odsParser.parseCommaSeparatedList(mlir::AsmParser::Delimiter::LessGreater,
62 if (odsParser.parseAttribute(element))
64 elements.insert(element);
65 elementType = element.getType();
70 auto setType = llvm::dyn_cast_or_null<SetType>(odsType);
71 if (odsType && !setType) {
72 odsParser.emitError(odsParser.getNameLoc())
73 <<
"type must be a an '!rtg.set' type";
77 if (!setType && elements.empty()) {
78 odsParser.emitError(odsParser.getNameLoc())
79 <<
"type must be explicitly provided: cannot infer set element type "
84 if (!setType && !elements.empty())
87 return SetAttr::getChecked(
88 odsParser.getEncodedSourceLoc(odsParser.getNameLoc()),
89 odsParser.getContext(), setType, &elements);
92void SetAttr::print(AsmPrinter &odsPrinter)
const {
95 SmallVector<std::string> sortedElements;
96 for (
auto element : *getElements()) {
97 std::string &elementStr = sortedElements.emplace_back();
98 llvm::raw_string_ostream elementOS(elementStr);
99 element.print(elementOS);
101 llvm::sort(sortedElements);
102 llvm::interleaveComma(sortedElements, odsPrinter);
110Type TupleAttr::getType()
const {
111 SmallVector<Type> elementTypes(llvm::map_range(
112 getElements(), [](
auto element) {
return element.getType(); }));
113 return TupleType::get(getContext(), elementTypes);
135 return (
value.getBitWidth() == key.getBitWidth() &&
value == key);
154Type ImmediateAttr::getType()
const {
155 return ImmediateType::get(getContext(), getValue().
getBitWidth());
158APInt ImmediateAttr::getValue()
const {
return getImpl()->value; }
160Attribute ImmediateAttr::parse(AsmParser &odsParser, Type odsType) {
161 llvm::SMLoc loc = odsParser.getCurrentLocation();
166 if (odsParser.parseLess() || odsParser.parseInteger(width) ||
167 odsParser.parseComma() || odsParser.parseInteger(val) ||
168 odsParser.parseGreater())
172 if (
auto immTy = llvm::dyn_cast_or_null<ImmediateType>(odsType)) {
173 if (immTy.getWidth() != width) {
174 odsParser.emitError(loc) <<
"explicit immediate type bit-width does not "
175 "match attribute bit-width, "
176 << immTy.getWidth() <<
" vs " << width;
181 if (width > val.getBitWidth()) {
185 val = val.sext(width);
186 }
else if (width < val.getBitWidth()) {
189 unsigned neededBits =
190 val.isNegative() ? val.getSignificantBits() : val.getActiveBits();
191 if (width < neededBits) {
192 odsParser.emitError(loc)
193 <<
"integer value out-of-range for bit-width " << width;
196 val = val.trunc(width);
199 return ImmediateAttr::get(odsParser.getContext(), val);
202void ImmediateAttr::print(AsmPrinter &odsPrinter)
const {
203 odsPrinter <<
"<" << getValue().getBitWidth() <<
", " << getValue() <<
">";
206Type VirtualRegisterConfigAttr::getType()
const {
207 return getAllowedRegs()[0].getType();
210LogicalResult VirtualRegisterConfigAttr::verify(
211 llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
212 ArrayRef<rtg::RegisterAttrInterface> allowedRegs) {
213 if (allowedRegs.empty())
214 return emitError() <<
"must have at least one allowed register";
216 if (!llvm::all_of(allowedRegs, [&](
auto reg) {
217 return reg.getType() == allowedRegs[0].getType();
219 return emitError() <<
"all allowed registers must be of the same type";
229void RTGDialect::registerAttributes() {
231#define GET_ATTRDEF_LIST
232#include "circt/Dialect/RTG/IR/RTGAttributes.cpp.inc"
236#define GET_ATTRDEF_CLASSES
237#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)