[mlir][ODS] Use StringLiteral instead of StringRef when applicable

Use `StringLiteral` for function return type if it is known to return
constant string literals only.

This will make it visible to API users, that such values can be safely
stored, since they refers to constant data, which will never be deallocated.

`StringRef` is general is not safe to store for a long term,
since it might refer to temporal data allocated in heap.

Add `inline` and `constexpr` methods support to `OpMethod`.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D97390
This commit is contained in:
Vladislav Vinogradov 2021-02-04 17:12:15 +00:00
parent e3b350ce83
commit 5d613e42d3
8 changed files with 44 additions and 9 deletions

View File

@ -238,6 +238,8 @@ public:
MP_Constructor = 0x2,
MP_Private = 0x4,
MP_Declaration = 0x8,
MP_Inline = 0x10,
MP_Constexpr = 0x20 | MP_Inline,
MP_StaticDeclaration = MP_Static | MP_Declaration,
};
@ -260,6 +262,9 @@ public:
// Returns true if this is a private method.
bool isPrivate() const { return properties & MP_Private; }
// Returns true if this is an inline method.
bool isInline() const { return properties & MP_Inline; }
// Returns the name of this method.
StringRef getName() const { return methodSignature.getName(); }

View File

@ -201,14 +201,25 @@ void OpMethod::writeDeclTo(raw_ostream &os) const {
os.indent(2);
if (isStatic())
os << "static ";
if (properties & MP_Constexpr)
os << "constexpr ";
methodSignature.writeDeclTo(os);
os << ";";
if (!isInline())
os << ";";
else {
os << " {\n";
methodBody.writeTo(os);
os << "}";
}
}
void OpMethod::writeDefTo(raw_ostream &os, StringRef namePrefix) const {
// Do not write definition if the method is decl only.
if (properties & MP_Declaration)
return;
// Do not generate separate definition for inline method
if (isInline())
return;
methodSignature.writeDefTo(os, namePrefix);
os << " {\n";
methodBody.writeTo(os);

View File

@ -71,7 +71,9 @@ def NS_AOp : NS_Op<"a_op", [IsolatedFromAbove, IsolatedFromAbove]> {
// CHECK: public:
// CHECK: using Op::Op;
// CHECK: using Adaptor = AOpAdaptor;
// CHECK: static ::llvm::StringRef getOperationName();
// CHECK: static constexpr ::llvm::StringLiteral getOperationName() {
// CHECK: return ::llvm::StringLiteral("test.a_op");
// CHECK: }
// CHECK: ::mlir::Operation::operand_range getODSOperands(unsigned index);
// CHECK: ::mlir::Value a();
// CHECK: ::mlir::Operation::operand_range b();

View File

@ -59,7 +59,9 @@ def B_CompoundTypeA : TestType<"CompoundA"> {
// DECL-LABEL: class CompoundAType : public ::mlir::Type
// DECL: static CompoundAType getChecked(llvm::function_ref<::mlir::InFlightDiagnostic()> emitError, ::mlir::MLIRContext *context, int widthOfSomething, ::mlir::test::SimpleTypeA exampleTdType, SomeCppStruct exampleCppType, ::llvm::ArrayRef<int> dims, ::mlir::Type inner);
// DECL: static ::mlir::LogicalResult verify(::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError, int widthOfSomething, ::mlir::test::SimpleTypeA exampleTdType, SomeCppStruct exampleCppType, ::llvm::ArrayRef<int> dims, ::mlir::Type inner);
// DECL: static ::llvm::StringRef getMnemonic() { return "cmpnd_a"; }
// DECL: static constexpr ::llvm::StringLiteral getMnemonic() {
// DECL: return ::llvm::StringLiteral("cmpnd_a");
// DECL: }
// DECL: static ::mlir::Type parse(::mlir::MLIRContext *context,
// DECL-NEXT: ::mlir::DialectAsmParser &parser);
// DECL: void print(::mlir::DialectAsmPrinter &printer) const;
@ -77,7 +79,9 @@ def C_IndexType : TestType<"Index"> {
);
// DECL-LABEL: class IndexType : public ::mlir::Type
// DECL: static ::llvm::StringRef getMnemonic() { return "index"; }
// DECL: static constexpr ::llvm::StringLiteral getMnemonic() {
// DECL: return ::llvm::StringLiteral("index");
// DECL: }
// DECL: static ::mlir::Type parse(::mlir::MLIRContext *context,
// DECL-NEXT: ::mlir::DialectAsmParser &parser);
// DECL: void print(::mlir::DialectAsmPrinter &printer) const;

View File

@ -75,7 +75,9 @@ class {0} : public ::mlir::Dialect {
void initialize();
friend class ::mlir::MLIRContext;
public:
static ::llvm::StringRef getDialectNamespace() { return "{1}"; }
static constexpr ::llvm::StringLiteral getDialectNamespace() {
return ::llvm::StringLiteral("{1}");
}
)";
/// Registration for a single dependent dialect: to be inserted in the ctor

View File

@ -2181,8 +2181,10 @@ void OpEmitter::genTraits() {
void OpEmitter::genOpNameGetter() {
auto *method = opClass.addMethodAndPrune(
"::llvm::StringRef", "getOperationName", OpMethod::MP_Static);
method->body() << " return \"" << op.getOperationName() << "\";\n";
"::llvm::StringLiteral", "getOperationName",
OpMethod::Property(OpMethod::MP_Static | OpMethod::MP_Constexpr));
method->body() << " return ::llvm::StringLiteral(\"" << op.getOperationName()
<< "\");";
}
void OpEmitter::genOpAsmInterface() {

View File

@ -45,13 +45,21 @@ const char *const passDeclBegin = R"(
template <typename DerivedT>
class {0}Base : public {1} {
public:
using Base = {0}Base;
{0}Base() : {1}(::mlir::TypeID::get<DerivedT>()) {{}
{0}Base(const {0}Base &) : {1}(::mlir::TypeID::get<DerivedT>()) {{}
/// Returns the command-line argument attached to this pass.
static constexpr ::llvm::StringLiteral getArgumentName() {
return ::llvm::StringLiteral("{2}");
}
::llvm::StringRef getArgument() const override { return "{2}"; }
/// Returns the derived pass name.
static constexpr ::llvm::StringLiteral getPassName() {
return ::llvm::StringLiteral("{0}");
}
::llvm::StringRef getName() const override { return "{0}"; }
/// Support isa/dyn_cast functionality for the derived pass class.

View File

@ -277,8 +277,9 @@ static void emitTypeDefDecl(const TypeDef &typeDef, raw_ostream &os) {
// Emit the mnenomic, if specified.
if (auto mnenomic = typeDef.getMnemonic()) {
os << " static ::llvm::StringRef getMnemonic() { return \"" << mnenomic
<< "\"; }\n";
os << " static constexpr ::llvm::StringLiteral getMnemonic() {\n"
<< " return ::llvm::StringLiteral(\"" << mnenomic << "\");\n"
<< " }\n";
// If mnemonic specified, emit print/parse declarations.
if (typeDef.getParserCode() || typeDef.getPrinterCode() || !params.empty())