14#include "mlir/IR/Builders.h"
15#include "mlir/IR/DialectImplementation.h"
16#include "mlir/Interfaces/FunctionImplementation.h"
31 SmallVectorImpl<Attribute> &resultNames,
32 SmallVectorImpl<Type> &resultTypes,
33 SmallVectorImpl<DictionaryAttr> &resultAttrs,
34 SmallVectorImpl<Attribute> &resultLocs) {
36 auto parseElt = [&]() -> ParseResult {
38 auto irLoc = parser.getCurrentLocation();
42 if (parser.parseKeywordOrString(&portName))
44 resultNames.push_back(StringAttr::get(parser.getContext(), portName));
47 resultTypes.emplace_back();
48 if (parser.parseColonType(resultTypes.back()))
53 if (failed(parser.parseOptionalAttrDict(
attrs)))
55 resultAttrs.push_back(
attrs.getDictionary(parser.getContext()));
58 std::optional<Location> maybeLoc;
59 if (failed(parser.parseOptionalLocationSpecifier(maybeLoc)))
61 Location loc = maybeLoc ? *maybeLoc : parser.getEncodedSourceLoc(irLoc);
62 resultLocs.push_back(loc);
67 return parser.parseCommaSeparatedList(OpAsmParser::Delimiter::Paren,
73 if (
auto mod = dyn_cast<HWModuleLike>(module)) {
74 if (argNo < mod.getNumInputPorts())
75 return mod.getInputName(argNo);
78 auto argNames =
module->getAttrOfType<ArrayAttr>("argNames");
80 if (argNames && argNo < argNames.size())
81 return cast<StringAttr>(argNames[argNo]).getValue();
86 if (
auto mod = dyn_cast<HWModuleLike>(module)) {
87 if (resultNo < mod.getNumOutputPorts())
88 return mod.getOutputName(resultNo);
91 auto resultNames =
module->getAttrOfType<ArrayAttr>("resultNames");
93 if (resultNames && resultNo < resultNames.size())
94 return cast<StringAttr>(resultNames[resultNo]).getValue();
99 ArrayRef<Type> argTypes,
101 ArrayRef<Type> resultTypes,
102 bool &needArgNamesAttr) {
103 using namespace mlir::function_interface_impl;
105 Region &body = op->getRegion(0);
106 bool isExternal = body.empty();
107 SmallString<32> resultNameStr;
108 mlir::OpPrintingFlags flags;
113 auto modOp = dyn_cast<hw::HWModuleLike>(op);
114 auto funcOp = dyn_cast<mlir::FunctionOpInterface>(op);
115 SmallVector<Attribute> inputAttrs, outputAttrs;
117 if (
auto args = funcOp.getAllArgAttrs())
118 for (
auto a : args.getValue())
119 inputAttrs.push_back(a);
120 inputAttrs.resize(funcOp.getNumArguments());
121 if (
auto results = funcOp.getAllResultAttrs())
122 for (
auto a : results.getValue())
123 outputAttrs.push_back(a);
124 outputAttrs.resize(funcOp.getNumResults());
126 inputAttrs = modOp.getAllInputAttrs();
127 outputAttrs = modOp.getAllOutputAttrs();
131 for (
unsigned i = 0, e = argTypes.size(); i < e; ++i) {
138 resultNameStr.clear();
139 llvm::raw_svector_ostream tmpStream(resultNameStr);
140 p.printOperand(body.front().getArgument(i), tmpStream);
143 if (tmpStream.str().drop_front() != argName)
144 needArgNamesAttr =
true;
146 p << tmpStream.str() <<
": ";
147 }
else if (!argName.empty()) {
148 p <<
'%' << argName <<
": ";
151 p.printType(argTypes[i]);
152 auto inputAttr = inputAttrs[i];
153 p.printOptionalAttrDict(inputAttr
154 ? cast<DictionaryAttr>(inputAttr).getValue()
155 : ArrayRef<NamedAttribute>());
160 if (flags.shouldPrintDebugInfo()) {
161 auto loc = modOp.getInputLoc(i);
162 if (!isa<UnknownLoc>(loc))
163 p.printOptionalLocationSpecifier(loc);
168 if (!argTypes.empty())
176 if (!resultTypes.empty()) {
178 for (
size_t i = 0, e = resultTypes.size(); i < e; ++i) {
183 p.printType(resultTypes[i]);
184 auto outputAttr = outputAttrs[i];
185 p.printOptionalAttrDict(outputAttr
186 ? cast<DictionaryAttr>(outputAttr).getValue()
187 : ArrayRef<NamedAttribute>());
192 if (flags.shouldPrintDebugInfo()) {
193 auto loc = modOp.getOutputLoc(i);
194 if (!isa<UnknownLoc>(loc))
195 p.printOptionalLocationSpecifier(loc);
203 OpAsmParser &parser,
bool &isVariadic,
204 SmallVectorImpl<OpAsmParser::Argument> &args,
205 SmallVectorImpl<Attribute> &argNames, SmallVectorImpl<Attribute> &argLocs,
206 SmallVectorImpl<Attribute> &resultNames,
207 SmallVectorImpl<DictionaryAttr> &resultAttrs,
208 SmallVectorImpl<Attribute> &resultLocs, TypeAttr &type) {
210 using namespace mlir::function_interface_impl;
211 auto *
context = parser.getContext();
214 if (parser.parseArgumentList(args, OpAsmParser::Delimiter::Paren,
219 SmallVector<Type> resultTypes;
220 if (succeeded(parser.parseOptionalArrow()))
222 resultAttrs, resultLocs)))
226 SmallVector<Type> argTypes;
227 for (
auto &arg : args) {
229 argTypes.push_back(arg.type);
231 arg.sourceLoc = parser.getEncodedSourceLoc(arg.ssaName.location);
232 argLocs.push_back(*arg.sourceLoc);
235 type = TypeAttr::get(FunctionType::get(
context, argTypes, resultTypes));
247ParseResult parseOptionalKeywordOrOptionalString(OpAsmParser &p,
251 if (succeeded(p.parseOptionalKeyword(&keyword))) {
252 result = keyword.str();
257 if (succeeded(p.parseOptionalString(&result)))
264 if (failed(p.parseKeyword(&key)))
265 return p.emitError(p.getCurrentLocation(),
"expected port direction");
268 else if (key ==
"out")
271 return p.emitError(p.getCurrentLocation(),
"unknown port direction '")
276static ParseResult parseInputPort(OpAsmParser &parser,
278 if (parser.parseOperand(result.ssaName,
false))
284 if (parseOptionalKeywordOrOptionalString(parser, result.
rawName,
found))
295 if (parser.parseColonType(result.type) ||
296 parser.parseOptionalAttrDict(
attrs) ||
297 parser.parseOptionalLocationSpecifier(result.sourceLoc))
299 result.attrs =
attrs.getDictionary(parser.getContext());
306 auto irLoc = parser.getCurrentLocation();
309 if (parser.parseKeywordOrString(&result.
rawName))
313 if (parser.parseColonType(result.type))
318 if (failed(parser.parseOptionalAttrDict(
attrs)))
320 result.attrs =
attrs.getDictionary(parser.getContext());
323 std::optional<Location> maybeLoc;
324 if (failed(parser.parseOptionalLocationSpecifier(maybeLoc)))
326 result.sourceLoc = maybeLoc ? *maybeLoc : parser.getEncodedSourceLoc(irLoc);
343 return parseInputPort(p, result);
348 SmallVectorImpl<module_like_impl::PortParse> &result) {
349 auto parseOnePort = [&]() -> ParseResult {
350 return parsePort(p, result.emplace_back());
352 return p.parseCommaSeparatedList(OpAsmParser::Delimiter::Paren, parseOnePort,
357 OpAsmParser &parser, SmallVectorImpl<PortParse> &args, TypeAttr &modType) {
359 auto *
context = parser.getContext();
366 SmallVector<ModulePort> ports;
367 for (
auto &arg : args) {
369 {StringAttr::get(
context, arg.rawName), arg.type, arg.direction});
372 arg.sourceLoc = parser.getEncodedSourceLoc(arg.ssaName.location);
374 modType = TypeAttr::get(ModuleType::get(
context, ports));
384 assert(0 &&
"Unknown port direction");
389 hw::HWModuleLike op) {
391 p, op.getModuleBody(), op.getHWModuleType(), op.getAllPortAttrs(),
392 op.getAllPortLocs());
396 hw::ModuleType modType,
397 ArrayRef<Attribute> portAttrs,
398 ArrayRef<Location> locAttrs) {
399 bool isExternal = body.empty();
400 SmallString<32> resultNameStr;
401 mlir::OpPrintingFlags flags;
404 for (
auto [i, port] : llvm::enumerate(modType.getPorts())) {
410 p.printKeywordOrString(port.name);
414 resultNameStr.clear();
415 llvm::raw_svector_ostream tmpStream(resultNameStr);
416 p.printOperand(body.front().getArgument(curArg), tmpStream);
417 p <<
" " << tmpStream.str();
420 if (tmpStream.str().drop_front() != port.name) {
422 p.printKeywordOrString(port.name);
425 p <<
" %" << port.name.getValue();
430 p.printType(port.type);
431 if (!portAttrs.empty())
432 if (
auto attr = dyn_cast<DictionaryAttr>(portAttrs[i]))
433 p.printOptionalAttrDict(attr.getValue());
438 if (!locAttrs.empty() && flags.shouldPrintDebugInfo()) {
439 auto loc = locAttrs[i];
440 if (!isa<UnknownLoc>(loc))
441 p.printOptionalLocationSpecifier(cast<Location>(loc));
455 auto module = cast<HWModuleOp>(region.getParentOp());
457 auto *block = ®ion.front();
458 for (
size_t i = 0, e = block->getNumArguments(); i != e; ++i) {
459 auto name =
module.getInputName(i);
461 setNameFn(block->getArgument(i), name);
assert(baseType &&"element must be base type")
static std::unique_ptr< Context > context
static const char * directionAsString(ModulePort::Direction dir)
false return failure()
Parse an optional keyword or string and set instance into 'result'.
static ParseResult parsePortList(OpAsmParser &p, SmallVectorImpl< module_like_impl::PortParse > &result)
static StringRef getModuleResultName(Operation *module, size_t resultNo)
static ParseResult parseOutputPort(OpAsmParser &parser, module_like_impl::PortParse &result)
static ParseResult parsePort(OpAsmParser &p, module_like_impl::PortParse &result)
Parse a single argument with the following syntax:
static StringRef getModuleArgumentName(Operation *module, size_t argNo)
Return the port name for the specified argument or result.
static ParseResult parseFunctionResultList(OpAsmParser &parser, SmallVectorImpl< Attribute > &resultNames, SmallVectorImpl< Type > &resultTypes, SmallVectorImpl< DictionaryAttr > &resultAttrs, SmallVectorImpl< Attribute > &resultLocs)
Parse a function result list.
void printModuleSignature(OpAsmPrinter &p, Operation *op, ArrayRef< Type > argTypes, bool isVariadic, ArrayRef< Type > resultTypes, bool &needArgNamesAttr)
Print a module signature with named results.
ParseResult parseModuleSignature(OpAsmParser &parser, SmallVectorImpl< PortParse > &args, TypeAttr &modType)
New Style parsing.
ParseResult parseModuleFunctionSignature(OpAsmParser &parser, bool &isVariadic, SmallVectorImpl< OpAsmParser::Argument > &args, SmallVectorImpl< Attribute > &argNames, SmallVectorImpl< Attribute > &argLocs, SmallVectorImpl< Attribute > &resultNames, SmallVectorImpl< DictionaryAttr > &resultAttrs, SmallVectorImpl< Attribute > &resultLocs, TypeAttr &type)
This is a variant of mlir::parseFunctionSignature that allows names on result arguments.
void getAsmBlockArgumentNamesImpl(mlir::Region ®ion, OpAsmSetValueNameFn setNameFn)
Get a special name to use when printing the entry block arguments of the region contained by an opera...
void printModuleSignatureNew(OpAsmPrinter &p, Region &body, hw::ModuleType modType, ArrayRef< Attribute > portAttrs, ArrayRef< Location > locAttrs)
static StringAttr getNameFromSSA(MLIRContext *context, StringRef name)
Get a name from an SSA value string, if said value name is not a number.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
function_ref< void(Value, StringRef)> OpAsmSetValueNameFn
ModulePort::Direction direction