[fir] Move parser/printer/verifier of fir.string_lit and add builders

Move the parser, printer and verifier to the .cpp file. Add builders
needed for lowering.

This patch is part of the upstreaming effort from fir-dev branch.

Reviewed By: schweitz, mehdi_amini

Differential Revision: https://reviews.llvm.org/D110686

Co-authored-by: Valentin Clement <clementval@gmail.com>
This commit is contained in:
Eric Schweitz 2021-09-29 21:43:38 +02:00 committed by Valentin Clement
parent 8b8da01d88
commit a28896ae6a
No known key found for this signature in database
GPG Key ID: 086D54783C928776
2 changed files with 132 additions and 48 deletions

View File

@ -2777,56 +2777,25 @@ def fir_StringLitOp : fir_Op<"string_lit", [NoSideEffect]> {
let results = (outs fir_CharacterType);
let parser = [{
auto &builder = parser.getBuilder();
mlir::Attribute val;
mlir::NamedAttrList attrs;
llvm::SMLoc trailingTypeLoc;
if (parser.parseAttribute(val, "fake", attrs))
return mlir::failure();
if (auto v = val.dyn_cast<mlir::StringAttr>())
result.attributes.push_back(builder.getNamedAttr(value(), v));
else if (auto v = val.dyn_cast<mlir::ArrayAttr>())
result.attributes.push_back(builder.getNamedAttr(xlist(), v));
else
return parser.emitError(parser.getCurrentLocation(),
"found an invalid constant");
mlir::IntegerAttr sz;
mlir::Type type;
if (parser.parseLParen() ||
parser.parseAttribute(sz, size(), result.attributes) ||
parser.parseRParen() ||
parser.getCurrentLocation(&trailingTypeLoc) ||
parser.parseColonType(type))
return mlir::failure();
auto charTy = type.dyn_cast<fir::CharacterType>();
if (!charTy)
return parser.emitError(trailingTypeLoc,
"must have character type");
type = fir::CharacterType::get(builder.getContext(), charTy.getFKind(),
sz.getInt());
if (!type || parser.addTypesToList(type, result.types))
return mlir::failure();
return mlir::success();
}];
let parser = "return parseStringLitOp(parser, result);";
let printer = [{
p << ' ' << getValue() << '(';
p << getSize().cast<mlir::IntegerAttr>().getValue() << ") : ";
p.printType(getType());
}];
let printer = "::print(p, *this);";
let verifier = [{
if (getSize().cast<mlir::IntegerAttr>().getValue().isNegative())
return emitOpError("size must be non-negative");
if (auto xl = (*this)->getAttr(xlist())) {
auto xList = xl.cast<mlir::ArrayAttr>();
for (auto a : xList)
if (!a.isa<mlir::IntegerAttr>())
return emitOpError("values in list must be integers");
}
return mlir::success();
}];
let builders = [
OpBuilder<(ins "fir::CharacterType":$inType,
"llvm::StringRef":$value,
CArg<"llvm::Optional<int64_t>", "{}">:$len)>,
OpBuilder<(ins "fir::CharacterType":$inType,
"llvm::ArrayRef<char>":$xlist,
CArg<"llvm::Optional<int64_t>", "{}">:$len)>,
OpBuilder<(ins "fir::CharacterType":$inType,
"llvm::ArrayRef<char16_t>":$xlist,
CArg<"llvm::Optional<int64_t>", "{}">:$len)>,
OpBuilder<(ins "fir::CharacterType":$inType,
"llvm::ArrayRef<char32_t>":$xlist,
CArg<"llvm::Optional<int64_t>", "{}">:$len)>];
let verifier = "return ::verify(*this);";
let extraClassDeclaration = [{
static constexpr const char *size() { return "size"; }

View File

@ -1859,6 +1859,121 @@ bool fir::StringLitOp::isWideValue() {
return eleTy.cast<fir::CharacterType>().getFKind() != 1;
}
static mlir::NamedAttribute
mkNamedIntegerAttr(mlir::OpBuilder &builder, llvm::StringRef name, int64_t v) {
assert(v > 0);
return builder.getNamedAttr(
name, builder.getIntegerAttr(builder.getIntegerType(64), v));
}
void fir::StringLitOp::build(mlir::OpBuilder &builder, OperationState &result,
fir::CharacterType inType, llvm::StringRef val,
llvm::Optional<int64_t> len) {
auto valAttr = builder.getNamedAttr(value(), builder.getStringAttr(val));
int64_t length = len.hasValue() ? len.getValue() : inType.getLen();
auto lenAttr = mkNamedIntegerAttr(builder, size(), length);
result.addAttributes({valAttr, lenAttr});
result.addTypes(inType);
}
template <typename C>
static mlir::ArrayAttr convertToArrayAttr(mlir::OpBuilder &builder,
llvm::ArrayRef<C> xlist) {
llvm::SmallVector<mlir::Attribute> attrs;
auto ty = builder.getIntegerType(8 * sizeof(C));
for (auto ch : xlist)
attrs.push_back(builder.getIntegerAttr(ty, ch));
return builder.getArrayAttr(attrs);
}
void fir::StringLitOp::build(mlir::OpBuilder &builder, OperationState &result,
fir::CharacterType inType,
llvm::ArrayRef<char> vlist,
llvm::Optional<int64_t> len) {
auto valAttr =
builder.getNamedAttr(xlist(), convertToArrayAttr(builder, vlist));
std::int64_t length = len.hasValue() ? len.getValue() : inType.getLen();
auto lenAttr = mkNamedIntegerAttr(builder, size(), length);
result.addAttributes({valAttr, lenAttr});
result.addTypes(inType);
}
void fir::StringLitOp::build(mlir::OpBuilder &builder, OperationState &result,
fir::CharacterType inType,
llvm::ArrayRef<char16_t> vlist,
llvm::Optional<int64_t> len) {
auto valAttr =
builder.getNamedAttr(xlist(), convertToArrayAttr(builder, vlist));
std::int64_t length = len.hasValue() ? len.getValue() : inType.getLen();
auto lenAttr = mkNamedIntegerAttr(builder, size(), length);
result.addAttributes({valAttr, lenAttr});
result.addTypes(inType);
}
void fir::StringLitOp::build(mlir::OpBuilder &builder, OperationState &result,
fir::CharacterType inType,
llvm::ArrayRef<char32_t> vlist,
llvm::Optional<int64_t> len) {
auto valAttr =
builder.getNamedAttr(xlist(), convertToArrayAttr(builder, vlist));
std::int64_t length = len.hasValue() ? len.getValue() : inType.getLen();
auto lenAttr = mkNamedIntegerAttr(builder, size(), length);
result.addAttributes({valAttr, lenAttr});
result.addTypes(inType);
}
static mlir::ParseResult parseStringLitOp(mlir::OpAsmParser &parser,
mlir::OperationState &result) {
auto &builder = parser.getBuilder();
mlir::Attribute val;
mlir::NamedAttrList attrs;
llvm::SMLoc trailingTypeLoc;
if (parser.parseAttribute(val, "fake", attrs))
return mlir::failure();
if (auto v = val.dyn_cast<mlir::StringAttr>())
result.attributes.push_back(
builder.getNamedAttr(fir::StringLitOp::value(), v));
else if (auto v = val.dyn_cast<mlir::ArrayAttr>())
result.attributes.push_back(
builder.getNamedAttr(fir::StringLitOp::xlist(), v));
else
return parser.emitError(parser.getCurrentLocation(),
"found an invalid constant");
mlir::IntegerAttr sz;
mlir::Type type;
if (parser.parseLParen() ||
parser.parseAttribute(sz, fir::StringLitOp::size(), result.attributes) ||
parser.parseRParen() || parser.getCurrentLocation(&trailingTypeLoc) ||
parser.parseColonType(type))
return mlir::failure();
auto charTy = type.dyn_cast<fir::CharacterType>();
if (!charTy)
return parser.emitError(trailingTypeLoc, "must have character type");
type = fir::CharacterType::get(builder.getContext(), charTy.getFKind(),
sz.getInt());
if (!type || parser.addTypesToList(type, result.types))
return mlir::failure();
return mlir::success();
}
static void print(mlir::OpAsmPrinter &p, fir::StringLitOp &op) {
p << ' ' << op.getValue() << '(';
p << op.getSize().cast<mlir::IntegerAttr>().getValue() << ") : ";
p.printType(op.getType());
}
static mlir::LogicalResult verify(fir::StringLitOp &op) {
if (op.getSize().cast<mlir::IntegerAttr>().getValue().isNegative())
return op.emitOpError("size must be non-negative");
if (auto xl = op.getOperation()->getAttr(fir::StringLitOp::xlist())) {
auto xList = xl.cast<mlir::ArrayAttr>();
for (auto a : xList)
if (!a.isa<mlir::IntegerAttr>())
return op.emitOpError("values in list must be integers");
}
return mlir::success();
}
//===----------------------------------------------------------------------===//
// IfOp
//===----------------------------------------------------------------------===//