[mlir][tblgen] Emit deprecation warning if `kEmitRawAttributes` is used
authorMarkus Böck <markus.boeck02@gmail.com>
Thu, 12 Jan 2023 17:07:57 +0000 (18:07 +0100)
committerMarkus Böck <markus.boeck02@gmail.com>
Wed, 18 Jan 2023 09:16:08 +0000 (10:16 +0100)
As discussed in https://reviews.llvm.org/D140886, emitting a warning if the old API is used may be beneficial to encourage migration to the new fold API.
This reuse the existing `Deprecated` infrastructure within TableGen, and simply marks the `def` for `kEmitRawAttributesFolder` causing a use of it in a record (even if set within a base class) to emit a warning.

Error message as printed in the terminal:
```
Included from C:/llvm-project/mlir/python/mlir/dialects/TensorOps.td:13:
Included from C:/llvm-project/mlir/include\mlir/Dialect/Tensor/IR/TensorOps.td:12:
C:/llvm-project/mlir/include\mlir/Dialect/Tensor/IR/TensorBase.td:14:5: warning: Using deprecated def `kEmitRawAttributesFolder`
def Tensor_Dialect : Dialect {
    ^
note: 'useFoldAPI' of 'kEmitRawAttributesFolder' (default) has been deprecated and is pending removal. Please switch to 'kEmitFoldAdaptorFolder'. See https://discourse.llvm.org/t/psa-new-improved-fold-method-signature-has-landed-please-update-your-downstream-projects/67618
```

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

mlir/include/mlir/IR/DialectBase.td
mlir/include/mlir/IR/OpBase.td
mlir/lib/TableGen/Dialect.cpp
mlir/lib/Tools/mlir-tblgen/MlirTblgenMain.cpp
mlir/test/mlir-tblgen/has-fold-invalid-values.td

index 043019e..18ab90b 100644 (file)
 #ifndef DIALECTBASE_TD
 #define DIALECTBASE_TD
 
+// Helper for marking deprecated classes or defs. To mark a def as deprecated,
+// mix in the `Deprecate` class with a reason.
+class Deprecated<string reason> {
+  string odsDeprecated = reason;
+}
+
 //===----------------------------------------------------------------------===//
 // Dialect definitions
 //===----------------------------------------------------------------------===//
 
+class EmitFolderBase;
 // Generate 'fold' method with 'ArrayRef<Attribute>' parameter.
 // New code should prefer using 'kEmitFoldAdaptorFolder' and
 // consider 'kEmitRawAttributesFolder' deprecated and to be
 // removed in the future.
-defvar kEmitRawAttributesFolder = 0;
+def kEmitRawAttributesFolder : EmitFolderBase, Deprecated<
+  "'useFoldAPI' of 'kEmitRawAttributesFolder' (default) has been deprecated "
+  # "and is pending removal. Please switch to 'kEmitFoldAdaptorFolder'. See "
+  # "https://discourse.llvm.org/t/psa-new-improved-fold-method-signature-has-landed-please-update-your-downstream-projects/67618"
+> {}
 // Generate 'fold' method with 'FoldAdaptor' parameter.
-defvar kEmitFoldAdaptorFolder = 1;
+def kEmitFoldAdaptorFolder : EmitFolderBase {}
 
 class Dialect {
   // The name of the dialect.
@@ -95,7 +106,7 @@ class Dialect {
   bit isExtensible = 0;
 
   // Fold API to use for operations in this dialect.
-  int useFoldAPI = kEmitRawAttributesFolder;
+  EmitFolderBase useFoldAPI = kEmitRawAttributesFolder;
 }
 
 #endif // DIALECTBASE_TD
index a659371..00b70ab 100644 (file)
@@ -40,12 +40,6 @@ class StrFunc<string r> {
   string result = r;
 }
 
-// Helper for marking deprecated classes or defs. To mark a def as deprecated,
-// mix in the `Deprecate` class with a reason.
-class Deprecated<string reason> {
-  string odsDeprecated = reason;
-}
-
 //===----------------------------------------------------------------------===//
 // Predicate definitions
 //===----------------------------------------------------------------------===//
index 8d6b047..e41e2e7 100644 (file)
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "mlir/TableGen/Dialect.h"
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/TableGen/Error.h"
 #include "llvm/TableGen/Record.h"
 
@@ -103,13 +104,18 @@ bool Dialect::isExtensible() const {
 }
 
 Dialect::FolderAPI Dialect::getFolderAPI() const {
-  int64_t value = def->getValueAsInt("useFoldAPI");
-  if (value < static_cast<int64_t>(FolderAPI::RawAttributes) ||
-      value > static_cast<int64_t>(FolderAPI::FolderAdaptor))
+  llvm::Record *value = def->getValueAsDef("useFoldAPI");
+  auto converted =
+      llvm::StringSwitch<std::optional<Dialect::FolderAPI>>(value->getName())
+          .Case("kEmitRawAttributesFolder", FolderAPI::RawAttributes)
+          .Case("kEmitFoldAdaptorFolder", FolderAPI::FolderAdaptor)
+          .Default(std::nullopt);
+
+  if (!converted)
     llvm::PrintFatalError(def->getLoc(),
                           "Invalid value for dialect field `useFoldAPI`");
 
-  return static_cast<FolderAPI>(value);
+  return *converted;
 }
 
 bool Dialect::operator==(const Dialect &other) const {
index bfb5f33..564161f 100644 (file)
@@ -106,11 +106,6 @@ static void warnOfDeprecatedUses(RecordKeeper &records) {
         // Skip anonymous defs.
         if (jt.second->isAnonymous())
           continue;
-        // Skip all outside main file to avoid flagging redundantly.
-        unsigned buf =
-            SrcMgr.FindBufferContainingLoc(jt.second->getLoc().front());
-        if (buf != SrcMgr.getMainFileID())
-          continue;
 
         if (findUse(*jt.second, it.second->getDefInit(), hasUse)) {
           PrintWarning(jt.second->getLoc(),
index 09149a5..f61284d 100644 (file)
@@ -2,10 +2,12 @@
 
 include "mlir/IR/OpBase.td"
 
+def Bad : EmitFolderBase;
+
 def Test_Dialect : Dialect {
   let name = "test";
   let cppNamespace = "NS";
-  let useFoldAPI = 3;
+  let useFoldAPI = Bad;
 }
 
 def InvalidValue_Op : Op<Test_Dialect, "invalid_op"> {