14 #include "mlir/IR/Builders.h"
15 #include "mlir/IR/DialectImplementation.h"
16 #include "mlir/Interfaces/FunctionImplementation.h"
18 using namespace circt;
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))
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);
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")
270 else if (key ==
"inout")
273 return p.emitError(p.getCurrentLocation(),
"unknown port direction '")
280 if (parser.parseOperand(result.ssaName,
false))
297 if (parser.parseColonType(result.type) ||
298 parser.parseOptionalAttrDict(attrs) ||
299 parser.parseOptionalLocationSpecifier(result.sourceLoc))
301 result.attrs = attrs.getDictionary(parser.getContext());
308 auto irLoc = parser.getCurrentLocation();
311 if (parser.parseKeywordOrString(&result.
rawName))
315 if (parser.parseColonType(result.type))
320 if (failed(parser.parseOptionalAttrDict(attrs)))
322 result.attrs = attrs.getDictionary(parser.getContext());
325 std::optional<Location> maybeLoc;
326 if (failed(parser.parseOptionalLocationSpecifier(maybeLoc)))
328 result.sourceLoc = maybeLoc ? *maybeLoc : parser.getEncodedSourceLoc(irLoc);
350 SmallVectorImpl<module_like_impl::PortParse> &result) {
351 auto parseOnePort = [&]() -> ParseResult {
352 return parsePort(p, result.emplace_back());
354 return p.parseCommaSeparatedList(OpAsmParser::Delimiter::Paren, parseOnePort,
359 OpAsmParser &parser, SmallVectorImpl<PortParse> &args, TypeAttr &modType) {
361 auto *context = parser.getContext();
368 SmallVector<ModulePort> ports;
369 for (
auto &arg : args) {
376 arg.sourceLoc = parser.getEncodedSourceLoc(arg.ssaName.location);
390 assert(0 &&
"Unknown port direction");
395 hw::HWModuleLike op) {
397 p, op.getModuleBody(), op.getHWModuleType(), op.getAllPortAttrs(),
398 op.getAllPortLocs());
402 hw::ModuleType modType,
403 ArrayRef<Attribute> portAttrs,
404 ArrayRef<Location> locAttrs) {
405 bool isExternal = body.empty();
406 SmallString<32> resultNameStr;
407 mlir::OpPrintingFlags flags;
410 for (
auto [i, port] : llvm::enumerate(modType.getPorts())) {
416 p.printKeywordOrString(port.name);
420 resultNameStr.clear();
421 llvm::raw_svector_ostream tmpStream(resultNameStr);
422 p.printOperand(body.front().getArgument(curArg), tmpStream);
423 p <<
" " << tmpStream.str();
426 if (tmpStream.str().drop_front() != port.name) {
428 p.printKeywordOrString(port.name);
431 p <<
" %" << port.name.getValue();
436 p.printType(port.type);
437 if (!portAttrs.empty())
438 if (
auto attr = dyn_cast<DictionaryAttr>(portAttrs[i]))
439 p.printOptionalAttrDict(attr.getValue());
444 if (!locAttrs.empty() && flags.shouldPrintDebugInfo()) {
445 auto loc = locAttrs[i];
446 if (!isa<UnknownLoc>(loc))
447 p.printOptionalLocationSpecifier(cast<Location>(loc));
461 auto module = cast<HWModuleOp>(region.getParentOp());
463 auto *block = ®ion.front();
464 for (
size_t i = 0, e = block->getNumArguments(); i != e; ++i) {
465 auto name = module.getInputName(i);
467 setNameFn(block->getArgument(i), name);
assert(baseType &&"element must be base type")
static ParseResult parseDirection(OpAsmParser &p, ModulePort::Direction &dir)
static const char * directionAsString(ModulePort::Direction dir)
static ParseResult parsePortList(OpAsmParser &p, SmallVectorImpl< module_like_impl::PortParse > &result)
ParseResult parseOptionalKeywordOrOptionalString(OpAsmParser &p, std::string &result, bool &found)
Parse an optional keyword or string and set instance into 'result'.
static StringRef getModuleResultName(Operation *module, size_t resultNo)
static ParseResult parseInputPort(OpAsmParser &parser, module_like_impl::PortParse &result)
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.
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
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