16#include "mlir/IR/Builders.h"
17#include "llvm/Support/raw_ostream.h"
26LogicalResult InstanceOp::verify() {
28 auto libraryOps = body->getOps<OperatorLibraryOp>();
29 auto graphOps = body->getOps<DependenceGraphOp>();
31 if (std::distance(libraryOps.begin(), libraryOps.end()) != 1 ||
32 std::distance(graphOps.begin(), graphOps.end()) != 1)
34 <<
"must contain exactly one 'library' op and one 'graph' op";
36 if ((*graphOps.begin())->isBeforeInBlock(*libraryOps.begin()))
38 <<
"must contain the 'library' op followed by the 'graph' op";
44OperatorLibraryOp InstanceOp::getOperatorLibrary() {
45 return *getOps<OperatorLibraryOp>().begin();
48ResourceLibraryOp InstanceOp::getResourceLibrary() {
49 return *getOps<ResourceLibraryOp>().begin();
52DependenceGraphOp InstanceOp::getDependenceGraph() {
53 return *getOps<DependenceGraphOp>().begin();
60ParseResult OperationOp::parse(OpAsmParser &parser, OperationState &result) {
61 auto &builder = parser.getBuilder();
64 SmallVector<Attribute> alreadyParsed;
66 if (parser.parseLess())
70 auto parseSymbolResult = parser.parseOptionalAttribute(oprRef);
71 if (parseSymbolResult.has_value()) {
72 assert(succeeded(*parseSymbolResult));
73 alreadyParsed.push_back(builder.getAttr<LinkedOperatorTypeAttr>(oprRef));
76 if (parser.parseGreater())
81 (void)parser.parseOptionalSymbolName(opName, SymbolTable::getSymbolAttrName(),
85 SmallVector<OpAsmParser::UnresolvedOperand> unresolvedOperands;
86 SmallVector<Attribute> dependences;
87 unsigned operandIdx = 0;
88 auto parseDependenceSourceWithAttrDict = [&]() -> ParseResult {
89 llvm::SMLoc loc = parser.getCurrentLocation();
90 FlatSymbolRefAttr sourceRef;
94 auto parseSymbolResult = parser.parseOptionalAttribute(sourceRef);
95 if (parseSymbolResult.has_value())
96 assert(succeeded(*parseSymbolResult));
99 OpAsmParser::UnresolvedOperand operand;
100 if (parser.parseOperand(operand))
101 return parser.emitError(loc,
"expected SSA value or symbol reference");
103 unresolvedOperands.push_back(operand);
110 if (sourceRef || properties)
111 dependences.push_back(
112 builder.getAttr<DependenceAttr>(operandIdx, sourceRef, properties));
118 if (parser.parseCommaSeparatedList(AsmParser::Delimiter::Paren,
119 parseDependenceSourceWithAttrDict))
122 if (succeeded(parser.parseOptionalKeyword(
"uses"))) {
123 SmallVector<Attribute> rsrcRefs;
124 auto parseOne = [&]() -> ParseResult {
125 SymbolRefAttr rsrcRef;
126 if (parser.parseAttribute(rsrcRef))
127 return parser.emitError(parser.getCurrentLocation(),
128 "expected symbol reference inside uses[...]");
129 rsrcRefs.push_back(rsrcRef);
132 if (parser.parseCommaSeparatedList(OpAsmParser::Delimiter::Square,
136 auto linkedRsrcsAttr = builder.getAttr<LinkedResourceTypesAttr>(
137 builder.getArrayAttr(rsrcRefs));
139 alreadyParsed.push_back(linkedRsrcsAttr);
142 if (!dependences.empty())
143 result.addAttribute(builder.getStringAttr(
"dependences"),
144 builder.getArrayAttr(dependences));
147 ArrayAttr properties;
148 auto parsePropertiesResult =
150 if (parsePropertiesResult.has_value()) {
151 if (failed(*parsePropertiesResult))
153 result.addAttribute(builder.getStringAttr(
"sspProperties"), properties);
157 if (parser.parseOptionalAttrDict(result.attributes))
161 SmallVector<Value> operands;
162 if (parser.resolveOperands(unresolvedOperands, builder.getNoneType(),
165 result.addOperands(operands);
168 SmallVector<Type> types(parser.getNumResults(), builder.getNoneType());
169 result.addTypes(types);
174void OperationOp::print(OpAsmPrinter &p) {
176 SmallVector<Attribute> alreadyPrinted;
179 if (
auto linkedOpr = getLinkedOperatorTypeAttr()) {
180 p.printAttribute(linkedOpr.getValue());
181 alreadyPrinted.push_back(linkedOpr);
186 if (StringAttr symName = getSymNameAttr()) {
188 p.printSymbolName(symName);
195 SmallVector<DependenceAttr> defUseDeps(getNumOperands()), auxDeps;
196 if (ArrayAttr dependences = getDependencesAttr()) {
197 for (
auto dep : dependences.getAsRange<DependenceAttr>()) {
198 if (dep.getSourceRef())
199 auxDeps.push_back(dep);
201 defUseDeps[dep.getOperandIdx()] = dep;
206 llvm::interleaveComma((*this)->getOpOperands(), p, [&](OpOperand &operand) {
207 p.printOperand(operand.get());
208 if (DependenceAttr dep = defUseDeps[operand.getOperandNumber()]) {
210 p.printAttribute(dep.getProperties());
213 if (!auxDeps.empty()) {
214 if (!defUseDeps.empty())
216 llvm::interleaveComma(auxDeps, p, [&](DependenceAttr dep) {
217 p.printAttribute(dep.getSourceRef());
218 if (ArrayAttr depProps = dep.getProperties()) {
226 if (ArrayAttr properties = getSspPropertiesAttr()) {
227 for (
auto attr : properties) {
228 if (
auto linkedRsrcs = dyn_cast<LinkedResourceTypesAttr>(attr)) {
229 auto rsrcList = linkedRsrcs.getValue();
230 if (!rsrcList.empty()) {
232 llvm::interleaveComma(
233 rsrcList, p, [&](Attribute rsrc) { p.printAttribute(rsrc); });
236 alreadyPrinted.push_back(linkedRsrcs);
242 if (ArrayAttr properties = getSspPropertiesAttr()) {
248 SmallVector<StringRef> elidedAttrs = {
249 SymbolTable::getSymbolAttrName(),
250 OperationOp::getDependencesAttrName().getValue(),
251 OperationOp::getSspPropertiesAttrName().getValue()};
252 p.printOptionalAttrDict((*this)->getAttrs(), elidedAttrs);
255LogicalResult OperationOp::verify() {
256 ArrayAttr dependences = getDependencesAttr();
260 int nOperands = getNumOperands();
262 for (
auto dep : dependences.getAsRange<DependenceAttr>()) {
263 int idx = dep.getOperandIdx();
264 FlatSymbolRefAttr sourceRef = dep.getSourceRef();
268 if (idx >= nOperands)
270 "Operand index is out of bounds for def-use dependence attribute");
274 return emitError(
"Def-use operand indices in dependence attribute are "
275 "not monotonically increasing");
280 return emitError() <<
"Auxiliary dependence from " << sourceRef
281 <<
" is interleaved with SSA operands";
284 if (!((idx == lastIdx + 1) || (idx > lastIdx && idx == nOperands)))
285 return emitError(
"Auxiliary operand indices in dependence attribute "
286 "are not consecutive");
295OperationOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
296 auto instanceOp = (*this)->getParentOfType<InstanceOp>();
297 auto libraryOp = instanceOp.getOperatorLibrary();
298 auto graphOp = instanceOp.getDependenceGraph();
302 if (ArrayAttr dependences = getDependencesAttr())
303 for (
auto dep : dependences.getAsRange<DependenceAttr>()) {
304 FlatSymbolRefAttr sourceRef = dep.getSourceRef();
308 Operation *sourceOp = symbolTable.lookupSymbolIn(graphOp, sourceRef);
309 if (!sourceOp || !isa<OperationOp>(sourceOp)) {
311 "Auxiliary dependence references invalid source operation: ")
318 if (
auto linkedOpr = getLinkedOperatorTypeAttr()) {
319 SymbolRefAttr oprRef = linkedOpr.getValue();
322 oprOp = symbolTable.lookupSymbolIn(libraryOp, oprRef);
325 oprOp = symbolTable.lookupSymbolIn(instanceOp, oprRef);
328 oprOp = symbolTable.lookupNearestSymbolFrom(instanceOp->getParentOp(),
331 if (!oprOp || !isa<OperatorTypeOp>(oprOp))
332 return emitError(
"Linked operator type property references invalid "
340LinkedOperatorTypeAttr OperationOp::getLinkedOperatorTypeAttr() {
341 if (ArrayAttr properties = getSspPropertiesAttr()) {
342 const auto *it = llvm::find_if(
343 properties, [](Attribute a) {
return isa<LinkedOperatorTypeAttr>(a); });
344 if (it != properties.end())
345 return cast<LinkedOperatorTypeAttr>(*it);
350LinkedResourceTypesAttr OperationOp::getLinkedResourceTypesAttr() {
351 if (ArrayAttr properties = getSspPropertiesAttr()) {
352 const auto *it = llvm::find_if(properties, [](Attribute a) {
353 return isa<LinkedResourceTypesAttr>(a);
355 if (it != properties.end())
356 return cast<LinkedResourceTypesAttr>(*it);
367 if (!result.has_value() || succeeded(*result))
382#define GET_OP_CLASSES
383#include "circt/Dialect/SSP/SSP.cpp.inc"
assert(baseType &&"element must be base type")
static Block * getBodyBlock(FModuleLike mod)
static void printSSPProperties(OpAsmPrinter &p, Operation *op, ArrayAttr attr)
static ParseResult parseSSPProperties(OpAsmParser &parser, ArrayAttr &attr)
void printPropertyArray(ArrayAttr attr, AsmPrinter &p, ArrayRef< Attribute > alreadyPrinted={})
Print an array attribute, suppressing the #ssp.
mlir::OptionalParseResult parseOptionalPropertyArray(ArrayAttr &attr, AsmParser &parser, ArrayRef< Attribute > alreadyParsed={})
Parse an array of attributes while recognizing the properties of the SSP dialect even without a #ssp.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.