27 std::function<bool(Type,
bool)> hasInputRef = [&](Type type,
28 bool output) ->
bool {
29 auto ftype = type_dyn_cast<FIRRTLType>(type);
30 if (!ftype || !ftype.containsReference())
33 .
Case<RefType>([&](
auto reftype) {
return !output; })
34 .Case<OpenVectorType>([&](OpenVectorType ovt) {
35 return hasInputRef(ovt.getElementType(), output);
37 .Case<OpenBundleType>([&](OpenBundleType obt) {
38 for (
auto field : obt.getElements())
39 if (hasInputRef(field.type, field.isFlip ^ output))
45 for (
auto &pi :
module.getPorts())
46 if (hasInputRef(pi.type, pi.isOutput()))
47 return emitError(pi.loc, "input probe not allowed");
54 auto portTypes =
module.getPortTypesAttr();
55 if (!portTypes || llvm::any_of(portTypes.getValue(), [](Attribute attr) {
56 return !isa<TypeAttr>(attr);
58 return module.emitOpError("requires valid port types");
60 auto numPorts = portTypes.size();
63 auto portDirections =
module.getPortDirectionsAttr();
65 return module.emitOpError("requires valid port direction");
68 auto bitWidth = portDirections.size();
69 if (
static_cast<size_t>(bitWidth) != numPorts)
70 return module.emitOpError("requires ") << numPorts << " port directions";
73 auto portNames =
module.getPortNamesAttr();
75 return module.emitOpError("requires valid port names");
76 if (portNames.size() != numPorts)
77 return module.emitOpError("requires ") << numPorts << " port names";
78 if (llvm::any_of(portNames.getValue(),
79 [](Attribute attr) { return !isa<StringAttr>(attr); }))
80 return module.emitOpError("port names should all be string attributes");
83 auto portAnnotations =
module.getPortAnnotationsAttr();
85 return module.emitOpError("requires valid port annotations");
87 if (!portAnnotations.empty() && portAnnotations.size() != numPorts)
88 return module.emitOpError("requires ") << numPorts << " port annotations";
90 for (
auto annos : portAnnotations.getValue()) {
91 auto arrayAttr = dyn_cast<ArrayAttr>(annos);
93 return module.emitOpError(
94 "requires port annotations be array attributes");
95 if (llvm::any_of(arrayAttr.getValue(),
96 [](Attribute attr) { return !isa<DictionaryAttr>(attr); }))
97 return module.emitOpError(
98 "annotations must be dictionaries or subannotations");
102 auto portSymbols =
module.getPortSymbolsAttr();
104 return module.emitOpError("requires valid port symbols");
105 if (!portSymbols.empty() && portSymbols.size() != numPorts)
106 return module.emitOpError("requires ") << numPorts << " port symbols";
107 if (llvm::any_of(portSymbols.getValue(), [](Attribute attr) {
108 return !attr || !isa<hw::InnerSymAttr>(attr);
110 return module.emitOpError("port symbols should all be InnerSym attributes");
113 auto portLocs =
module.getPortLocationsAttr();
115 return module.emitOpError("requires valid port locations");
116 if (portLocs.size() != numPorts)
117 return module.emitOpError("requires ") << numPorts << " port locations";
118 if (llvm::any_of(portLocs.getValue(), [](Attribute attr) {
119 return !attr || !isa<LocationAttr>(attr);
121 return module.emitOpError("port symbols should all be location attributes");
124 if (module->getNumRegions() != 1)
125 return module.emitOpError("requires one region");
214 OperationState state(op.getLoc(), op->getName(), op->getOperands(),
Forceable replaceWithNewForceability(Forceable op, bool forceable, ::mlir::PatternRewriter *rewriter=nullptr)
Replace a Forceable op with equivalent, changing whether forceable.