17#include "mlir/IR/BuiltinAttributes.h"
18#include "mlir/IR/BuiltinTypes.h"
19#include "llvm/ADT/SmallBitVector.h"
20#include "llvm/ADT/SmallPtrSet.h"
21#include "llvm/ADT/StringRef.h"
27 return attrs.getAs<::circt::hw::InnerSymAttr>(
28 hw::HWModuleLike::getPortSymbolAttrName());
34 StringAttr::get(ctx, hw::HWModuleLike::getPortSymbolAttrName());
35 NamedAttrList pattr(
attrs);
38 oldValue = pattr.erase(portSymAttr);
40 oldValue = pattr.set(portSymAttr, sym);
41 if (oldValue != sym) {
42 attrs = pattr.getDictionary(ctx);
48 if (
auto updatedName =
attrs.get(
"hw.verilogName"))
49 return cast<StringAttr>(updatedName).getValue();
50 return name.getValue();
55 llvm::function_ref<InFlightDiagnostic()> emitError) {
56 assert(innerSym &&
"null inner symbol attribute provided");
66 for (
auto prop : innerSym) {
67 if (prop.getFieldID() != 0)
68 return emitError() <<
"does not support per-field inner symbols, but "
70 << prop.getName().getValue()
71 <<
"' with non-zero field id " << prop.getFieldID();
74 if (innerSym.size() > 1) {
76 auto err = emitError() <<
"has more than one symbol defined: ";
77 llvm::interleaveComma(innerSym, err, [&](
auto prop) {
78 err <<
"'" << prop.getName().getValue() <<
"'";
86 llvm::SmallBitVector indices(maxFields + 1);
87 llvm::SmallPtrSet<Attribute, 8> symNames;
89 auto uniqSyms = [&](InnerSymPropertiesAttr p) {
90 if (maxFields < p.getFieldID()) {
91 emitError() <<
"field id " << p.getFieldID()
92 <<
" is greater than the maximum field id " << maxFields;
95 if (indices.test(p.getFieldID())) {
96 emitError() <<
"cannot assign multiple symbol names to the field id "
100 indices.set(p.getFieldID());
101 auto it = symNames.insert(p.getName());
103 emitError() <<
"cannot reuse symbol name '" << p.getName().getValue()
110 if (!llvm::all_of(innerSym.getProps(), uniqSyms))
117 auto innerSym = op.getInnerSymAttr();
122 if (innerSym.empty())
123 return op->emitOpError(
"has empty list of inner symbols");
125 if (!op.supportsPerFieldSymbols())
131 auto result = op.getTargetResult();
136 [op]() { return op->emitOpError(); });
140 assert(op->hasTrait<OpTrait::InnerSymbolTable>());
141 PortList opWithPorts = dyn_cast<hw::PortList>(op);
146 auto ports = opWithPorts.getPortList();
147 for (
auto const &indexAndPort : llvm::enumerate(ports)) {
148 auto &pi = indexAndPort.value();
149 auto idx = indexAndPort.index();
150 Location loc = pi.loc ? Location(pi.loc) : opWithPorts.getLoc();
151 if (
auto sym = pi.getSym())
153 return mlir::emitError(loc)
154 <<
"verification of inner symbol"
155 << (sym.size() > 1 ?
"s" :
"") <<
" failed on port " << idx
156 <<
" with name " << pi.name <<
": ";
174 printer << dirstr <<
" " << port.
name <<
" : " << port.
type <<
" (argnum "
176 <<
", args " << port.
attrs <<
")";
180#include "circt/Dialect/HW/HWOpInterfaces.cpp.inc"
assert(baseType &&"element must be base type")
false return failure()
Parse an optional keyword or string and set instance into 'result'.
uint64_t getMaxFieldID(Type)
LogicalResult verifyPortInnerSymsIfPortList(Operation *op)
Verification hook for verifying InnerSymbol-defining operations.
OS & operator<<(OS &os, const InnerSymTarget &target)
Printing InnerSymTarget's.
LogicalResult verifyInnerSymAttr(InnerSymAttr innerSym, Type type, llvm::function_ref< InFlightDiagnostic()> emitError)
LogicalResult verifyInnerSymOp(InnerSymbolOpInterface op)
Verification hook for verifying InnerSymbol-defining operations.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
This holds the name, type, direction of a module's ports.
StringRef getVerilogName() const
DictionaryAttr attrs
The optional symbol for this port.
size_t argNum
This is the argument index or the result index depending on the direction.
void setSym(InnerSymAttr sym, MLIRContext *ctx)
InnerSymAttr getSym() const