Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[HW] [NFC] Extract out printing/parsing functions for modules (#1773)
- Loading branch information
Showing
4 changed files
with
233 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
//===- ModuleImplementation.h - Module-like Op utilities --------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This file provides utility functions for implementing module-like | ||
// operations, in particular, parsing, and printing common to module-like | ||
// operations. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef CIRCT_DIALECT_HW_MODULEIMPLEMENTATION_H | ||
#define CIRCT_DIALECT_HW_MODULEIMPLEMENTATION_H | ||
|
||
#include "circt/Support/LLVM.h" | ||
|
||
#include "mlir/IR/DialectImplementation.h" | ||
|
||
namespace circt { | ||
namespace hw { | ||
|
||
namespace module_like_impl { | ||
|
||
/// Parse a portname as a keyword or a quote surrounded string, followed by a | ||
/// colon. | ||
StringAttr parsePortName(OpAsmParser &parser); | ||
|
||
/// Get the portname from an SSA value string, if said value name is not a | ||
/// number. | ||
StringAttr getPortNameAttr(MLIRContext *context, StringRef name); | ||
|
||
/// This is a variant of mlor::parseFunctionSignature that allows names on | ||
/// result arguments. | ||
ParseResult parseModuleFunctionSignature( | ||
OpAsmParser &parser, SmallVectorImpl<OpAsmParser::OperandType> &argNames, | ||
SmallVectorImpl<Type> &argTypes, SmallVectorImpl<NamedAttrList> &argAttrs, | ||
bool &isVariadic, SmallVectorImpl<Type> &resultTypes, | ||
SmallVectorImpl<NamedAttrList> &resultAttrs, | ||
SmallVectorImpl<Attribute> &resultNames); | ||
|
||
/// Parse a function result list with named results. | ||
ParseResult parseFunctionResultList(OpAsmParser &parser, | ||
SmallVectorImpl<Type> &resultTypes, | ||
SmallVectorImpl<NamedAttrList> &resultAttrs, | ||
SmallVectorImpl<Attribute> &resultNames); | ||
|
||
/// Print a module signature with named results. | ||
void printModuleSignature(OpAsmPrinter &p, Operation *op, | ||
ArrayRef<Type> argTypes, bool isVariadic, | ||
ArrayRef<Type> resultTypes, bool &needArgNamesAttr); | ||
|
||
} // namespace module_like_impl | ||
} // namespace hw | ||
} // namespace circt | ||
|
||
#endif // CIRCT_DIALECT_HW_MODULEIMPLEMENTATION_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
//===- ModuleImplementation.cpp - Utilities for module-like ops -----------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "circt/Dialect/HW/ModuleImplementation.h" | ||
#include "circt/Dialect/HW/HWOps.h" | ||
#include "circt/Support/LLVM.h" | ||
|
||
#include "mlir/IR/Builders.h" | ||
#include "mlir/IR/DialectImplementation.h" | ||
#include "mlir/IR/FunctionImplementation.h" | ||
|
||
using namespace mlir; | ||
using namespace circt::hw; | ||
|
||
/// Get the portname from an SSA value string, if said value name is not a | ||
/// number | ||
StringAttr module_like_impl::getPortNameAttr(MLIRContext *context, | ||
StringRef name) { | ||
if (!name.empty()) { | ||
// Ignore numeric names like %42 | ||
assert(name.size() > 1 && name[0] == '%' && "Unknown MLIR name"); | ||
if (isdigit(name[1])) | ||
name = StringRef(); | ||
else | ||
name = name.drop_front(); | ||
} | ||
return StringAttr::get(context, name); | ||
} | ||
|
||
/// Parse a portname as a keyword or a quote surrounded string, followed by a | ||
/// colon. | ||
StringAttr module_like_impl::parsePortName(OpAsmParser &parser) { | ||
StringAttr result; | ||
StringRef keyword; | ||
if (succeeded(parser.parseOptionalKeyword(&keyword))) { | ||
result = parser.getBuilder().getStringAttr(keyword); | ||
} else if (parser.parseAttribute(result, | ||
parser.getBuilder().getType<NoneType>())) | ||
return {}; | ||
return succeeded(parser.parseColon()) ? result : StringAttr(); | ||
} | ||
|
||
/// Parse a function result list. | ||
/// | ||
/// function-result-list ::= function-result-list-parens | ||
/// function-result-list-parens ::= `(` `)` | ||
/// | `(` function-result-list-no-parens `)` | ||
/// function-result-list-no-parens ::= function-result (`,` function-result)* | ||
/// function-result ::= (percent-identifier `:`) type attribute-dict? | ||
/// | ||
ParseResult module_like_impl::parseFunctionResultList( | ||
OpAsmParser &parser, SmallVectorImpl<Type> &resultTypes, | ||
SmallVectorImpl<NamedAttrList> &resultAttrs, | ||
SmallVectorImpl<Attribute> &resultNames) { | ||
if (parser.parseLParen()) | ||
return failure(); | ||
|
||
// Special case for an empty set of parens. | ||
if (succeeded(parser.parseOptionalRParen())) | ||
return success(); | ||
|
||
// Parse individual function results. | ||
do { | ||
resultNames.push_back(parsePortName(parser)); | ||
if (!resultNames.back()) | ||
return failure(); | ||
|
||
resultTypes.emplace_back(); | ||
resultAttrs.emplace_back(); | ||
if (parser.parseType(resultTypes.back()) || | ||
parser.parseOptionalAttrDict(resultAttrs.back())) | ||
return failure(); | ||
} while (succeeded(parser.parseOptionalComma())); | ||
return parser.parseRParen(); | ||
} | ||
|
||
/// This is a variant of mlor::parseFunctionSignature that allows names on | ||
/// result arguments. | ||
ParseResult module_like_impl::parseModuleFunctionSignature( | ||
OpAsmParser &parser, SmallVectorImpl<OpAsmParser::OperandType> &argNames, | ||
SmallVectorImpl<Type> &argTypes, SmallVectorImpl<NamedAttrList> &argAttrs, | ||
bool &isVariadic, SmallVectorImpl<Type> &resultTypes, | ||
SmallVectorImpl<NamedAttrList> &resultAttrs, | ||
SmallVectorImpl<Attribute> &resultNames) { | ||
|
||
using namespace mlir::function_like_impl; | ||
bool allowArgAttrs = true; | ||
bool allowVariadic = false; | ||
if (parseFunctionArgumentList(parser, allowArgAttrs, allowVariadic, argNames, | ||
argTypes, argAttrs, isVariadic)) | ||
return failure(); | ||
|
||
if (succeeded(parser.parseOptionalArrow())) | ||
return parseFunctionResultList(parser, resultTypes, resultAttrs, | ||
resultNames); | ||
return success(); | ||
} | ||
|
||
void circt::hw::module_like_impl::printModuleSignature( | ||
OpAsmPrinter &p, Operation *op, ArrayRef<Type> argTypes, bool isVariadic, | ||
ArrayRef<Type> resultTypes, bool &needArgNamesAttr) { | ||
Region &body = op->getRegion(0); | ||
bool isExternal = body.empty(); | ||
SmallString<32> resultNameStr; | ||
|
||
p << '('; | ||
for (unsigned i = 0, e = argTypes.size(); i < e; ++i) { | ||
if (i > 0) | ||
p << ", "; | ||
|
||
auto argName = getModuleArgumentName(op, i); | ||
|
||
if (!isExternal) { | ||
// Get the printed format for the argument name. | ||
resultNameStr.clear(); | ||
llvm::raw_svector_ostream tmpStream(resultNameStr); | ||
p.printOperand(body.front().getArgument(i), tmpStream); | ||
|
||
// If the name wasn't printable in a way that agreed with argName, make | ||
// sure to print out an explicit argNames attribute. | ||
if (tmpStream.str().drop_front() != argName) | ||
needArgNamesAttr = true; | ||
|
||
p << tmpStream.str() << ": "; | ||
} else if (!argName.empty()) { | ||
p << '%' << argName << ": "; | ||
} | ||
|
||
p.printType(argTypes[i]); | ||
p.printOptionalAttrDict(::mlir::function_like_impl::getArgAttrs(op, i)); | ||
} | ||
|
||
if (isVariadic) { | ||
if (!argTypes.empty()) | ||
p << ", "; | ||
p << "..."; | ||
} | ||
|
||
p << ')'; | ||
|
||
// We print result types specially since we support named arguments. | ||
if (!resultTypes.empty()) { | ||
auto &os = p.getStream(); | ||
os << " -> ("; | ||
for (size_t i = 0, e = resultTypes.size(); i < e; ++i) { | ||
if (i != 0) | ||
os << ", "; | ||
StringRef name = getModuleResultName(op, i); | ||
if (!name.empty()) | ||
os << '%' << name << ": "; | ||
|
||
p.printType(resultTypes[i]); | ||
p.printOptionalAttrDict( | ||
::mlir::function_like_impl::getResultAttrs(op, i)); | ||
} | ||
os << ')'; | ||
} | ||
} |