[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:
parent
8b8da01d88
commit
a28896ae6a
|
|
@ -2777,56 +2777,25 @@ def fir_StringLitOp : fir_Op<"string_lit", [NoSideEffect]> {
|
||||||
|
|
||||||
let results = (outs fir_CharacterType);
|
let results = (outs fir_CharacterType);
|
||||||
|
|
||||||
let parser = [{
|
let parser = "return parseStringLitOp(parser, 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(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 printer = [{
|
let printer = "::print(p, *this);";
|
||||||
p << ' ' << getValue() << '(';
|
|
||||||
p << getSize().cast<mlir::IntegerAttr>().getValue() << ") : ";
|
|
||||||
p.printType(getType());
|
|
||||||
}];
|
|
||||||
|
|
||||||
let verifier = [{
|
let builders = [
|
||||||
if (getSize().cast<mlir::IntegerAttr>().getValue().isNegative())
|
OpBuilder<(ins "fir::CharacterType":$inType,
|
||||||
return emitOpError("size must be non-negative");
|
"llvm::StringRef":$value,
|
||||||
if (auto xl = (*this)->getAttr(xlist())) {
|
CArg<"llvm::Optional<int64_t>", "{}">:$len)>,
|
||||||
auto xList = xl.cast<mlir::ArrayAttr>();
|
OpBuilder<(ins "fir::CharacterType":$inType,
|
||||||
for (auto a : xList)
|
"llvm::ArrayRef<char>":$xlist,
|
||||||
if (!a.isa<mlir::IntegerAttr>())
|
CArg<"llvm::Optional<int64_t>", "{}">:$len)>,
|
||||||
return emitOpError("values in list must be integers");
|
OpBuilder<(ins "fir::CharacterType":$inType,
|
||||||
}
|
"llvm::ArrayRef<char16_t>":$xlist,
|
||||||
return mlir::success();
|
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 = [{
|
let extraClassDeclaration = [{
|
||||||
static constexpr const char *size() { return "size"; }
|
static constexpr const char *size() { return "size"; }
|
||||||
|
|
|
||||||
|
|
@ -1859,6 +1859,121 @@ bool fir::StringLitOp::isWideValue() {
|
||||||
return eleTy.cast<fir::CharacterType>().getFKind() != 1;
|
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
|
// IfOp
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue