14 #include "mlir/IR/DialectImplementation.h"
15 #include "llvm/ADT/SmallPtrSet.h"
16 #include "llvm/ADT/TypeSwitch.h"
18 using namespace circt;
25 #define GET_ATTRDEF_CLASSES
26 #include "circt/Dialect/SV/SVAttributes.cpp.inc"
28 #include "circt/Dialect/SV/SVEnums.cpp.inc"
30 void SVDialect::registerAttributes() {
32 #define GET_ATTRDEF_LIST
33 #include "circt/Dialect/SV/SVAttributes.cpp.inc"
43 return !attrs.empty();
48 auto attrs = op->getAttr(SVAttributeAttr::getSVAttributesAttrName());
51 auto arrayAttr = dyn_cast<ArrayAttr>(attrs);
53 op->emitOpError(
"'sv.attributes' must be an array attribute");
56 for (
auto attr : arrayAttr) {
57 if (!isa<SVAttributeAttr>(attr)) {
58 op->emitOpError(
"'sv.attributes' elements must be `SVAttributeAttr`s");
62 if (arrayAttr.empty())
68 if (attrs && !attrs.getValue().empty())
69 op->setAttr(SVAttributeAttr::getSVAttributesAttrName(), attrs);
71 op->removeAttr(SVAttributeAttr::getSVAttributesAttrName());
77 SmallVector<Attribute> filteredAttrs;
78 SmallPtrSet<Attribute, 4> seenAttrs;
79 filteredAttrs.reserve(attrs.size());
80 for (
auto attr : attrs)
81 if (seenAttrs.insert(attr).second)
82 filteredAttrs.push_back(attr);
87 Operation *op, llvm::function_ref<
void(SmallVectorImpl<SVAttributeAttr> &)>
89 ArrayRef<Attribute> oldAttrs;
91 oldAttrs = attrs.getValue();
93 SmallVector<SVAttributeAttr> newAttrs;
94 newAttrs.reserve(oldAttrs.size());
95 for (
auto oldAttr : oldAttrs)
96 newAttrs.push_back(cast<SVAttributeAttr>(oldAttr));
97 modifyCallback(newAttrs);
99 if (newAttrs.size() == oldAttrs.size() &&
100 llvm::none_of(llvm::zip(oldAttrs, newAttrs), [](
auto pair) {
101 return std::get<0>(pair) != std::get<1>(pair);
110 ArrayRef<SVAttributeAttr> newAttrs) {
111 if (newAttrs.empty())
113 unsigned numAdded = 0;
115 SmallPtrSet<Attribute, 4> seenAttrs(attrs.begin(), attrs.end());
116 for (
auto newAttr : newAttrs) {
117 if (seenAttrs.insert(newAttr).second) {
118 attrs.push_back(newAttr);
127 Operation *op, llvm::function_ref<
bool(SVAttributeAttr)> removeCallback) {
128 unsigned numRemoved = 0;
131 unsigned inIdx = 0, outIdx = 0, endIdx = attrs.size();
132 for (; inIdx != endIdx; ++inIdx) {
133 if (removeCallback(attrs[inIdx]))
136 attrs[outIdx++] = attrs[inIdx];
138 attrs.truncate(outIdx);
144 ArrayRef<SVAttributeAttr> attrs) {
145 SmallPtrSet<Attribute, 4> attrSet;
146 for (
auto attr : attrs)
147 attrSet.insert(attr);
149 [&](
auto attr) {
return attrSet.contains(attr); });
156 mlir::Attribute SVAttributeAttr::parse(mlir::AsmParser &p, mlir::Type type) {
158 if (p.parseLess() || p.parseAttribute(nameAttr))
161 StringAttr expressionAttr;
162 if (!p.parseOptionalEqual())
163 if (p.parseAttribute(expressionAttr))
166 bool emitAsComment =
false;
167 if (!p.parseOptionalComma()) {
168 if (p.parseKeyword(
"emitAsComment"))
170 emitAsComment =
true;
173 if (p.parseGreater())
180 void SVAttributeAttr::print(::mlir::AsmPrinter &p)
const {
182 if (
auto expr = getExpression())
184 if (getEmitAsComment().getValue())
185 p <<
", emitAsComment";
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
StringAttr getName(ArrayAttr names, size_t idx)
Return the name at the specified index of the ArrayAttr or null if it cannot be determined.
mlir::ArrayAttr getSVAttributes(mlir::Operation *op)
Return all the SV attributes of an operation, or null if there are none.
unsigned removeSVAttributes(mlir::Operation *op, llvm::function_ref< bool(SVAttributeAttr)> removeCallback)
Remove the SV attributes from an operation for which removeCallback returns true.
bool modifySVAttributes(mlir::Operation *op, llvm::function_ref< void(llvm::SmallVectorImpl< SVAttributeAttr > &)> modifyCallback)
Modify the list of SV attributes of an operation.
bool hasSVAttributes(mlir::Operation *op)
Helper functions to handle SV attributes.
unsigned addSVAttributes(mlir::Operation *op, llvm::ArrayRef< SVAttributeAttr > attrs)
Add a list of SV attributes to an operation.
void setSVAttributes(mlir::Operation *op, mlir::ArrayAttr attrs)
Set the SV attributes of an operation.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.