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"
41bool sv::hasSVAttributes(Operation *op) {
43 return !attrs.empty();
47ArrayAttr sv::getSVAttributes(Operation *op) {
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())
67void sv::setSVAttributes(Operation *op, ArrayAttr attrs) {
68 if (attrs && !attrs.getValue().empty())
69 op->setAttr(SVAttributeAttr::getSVAttributesAttrName(), attrs);
71 op->removeAttr(SVAttributeAttr::getSVAttributesAttrName());
74void sv::setSVAttributes(Operation *op, ArrayRef<SVAttributeAttr> attrs) {
76 return sv::setSVAttributes(op, ArrayAttr());
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);
83 sv::setSVAttributes(op, ArrayAttr::get(op->getContext(), filteredAttrs));
86bool sv::modifySVAttributes(
87 Operation *op, llvm::function_ref<
void(SmallVectorImpl<SVAttributeAttr> &)>
89 ArrayRef<Attribute> oldAttrs;
90 if (
auto attrs = sv::getSVAttributes(op))
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);
105 sv::setSVAttributes(op, newAttrs);
109unsigned sv::addSVAttributes(Operation *op,
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);
126unsigned sv::removeSVAttributes(
127 Operation *op, llvm::function_ref<
bool(SVAttributeAttr)> removeCallback) {
128 unsigned numRemoved = 0;
129 sv::modifySVAttributes(op, [&](
auto &attrs) {
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);
143unsigned sv::removeSVAttributes(Operation *op,
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.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.