14#include "mlir/IR/DialectImplementation.h"
15#include "llvm/ADT/SmallPtrSet.h"
16#include "llvm/ADT/TypeSwitch.h"
25#define GET_ATTRDEF_CLASSES
26#include "circt/Dialect/SV/SVAttributes.cpp.inc"
28#include "circt/Dialect/SV/SVEnums.cpp.inc"
30void 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())
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]))
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); });
156mlir::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())
176 return SVAttributeAttr::get(p.getContext(), nameAttr, expressionAttr,
177 BoolAttr::get(p.getContext(), emitAsComment));
180void SVAttributeAttr::print(::mlir::AsmPrinter &p)
const {
182 if (
auto expr = getExpression())
184 if (getEmitAsComment().getValue())
185 p <<
", emitAsComment";
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.