[mlir][ODS] Use StringLiteral instead of StringRef when applicable
authorVladislav Vinogradov <vlad.vinogradov@intel.com>
Thu, 4 Feb 2021 17:12:15 +0000 (17:12 +0000)
committerVladislav Vinogradov <vlad.vinogradov@intel.com>
Wed, 3 Mar 2021 13:15:12 +0000 (16:15 +0300)
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

mlir/include/mlir/TableGen/OpClass.h
mlir/lib/TableGen/OpClass.cpp
mlir/test/mlir-tblgen/op-decl-and-defs.td
mlir/test/mlir-tblgen/typedefs.td
mlir/tools/mlir-tblgen/DialectGen.cpp
mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
mlir/tools/mlir-tblgen/PassGen.cpp
mlir/tools/mlir-tblgen/TypeDefGen.cpp

index a82b9dd..243e7fa 100644 (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(); }
 
index 2fad62e..ae20a17 100644 (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);
index 220ab8c..ebdaaa4 100644 (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();
index 98d97eb..a895c5c 100644 (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;
index 43f3968..8eaf17c 100644 (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
index 9fc6ecf..e137df4 100644 (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() {
index c1664a0..a33297e 100644 (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.
index f26d6a2..689c35e 100644 (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())