[Mlir-commits] [mlir] 91e8a63 - [mlir] Support verification order (1/3)

Chia-hung Duan llvmlistbot at llvm.org
Wed Feb 2 10:27:34 PST 2022


Author: Chia-hung Duan
Date: 2022-02-02T18:25:44Z
New Revision: 91e8a63c20ea5a040de89143944e842c4d422b68

URL: https://github.com/llvm/llvm-project/commit/91e8a63c20ea5a040de89143944e842c4d422b68
DIFF: https://github.com/llvm/llvm-project/commit/91e8a63c20ea5a040de89143944e842c4d422b68.diff

LOG: [mlir] Support verification order (1/3)

This CL supports adding dependency between traits verifiers and the
dependency will be checked statically.

Reviewed By: jpienaar

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

Added: 
    

Modified: 
    mlir/include/mlir/IR/OpBase.td
    mlir/lib/TableGen/Operator.cpp
    mlir/test/mlir-tblgen/op-error.td

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/IR/OpBase.td b/mlir/include/mlir/IR/OpBase.td
index 4d64af296d2fc..992ae35e4548b 100644
--- a/mlir/include/mlir/IR/OpBase.td
+++ b/mlir/include/mlir/IR/OpBase.td
@@ -2024,11 +2024,31 @@ class PredAttrTrait<string descr, Pred pred> : PredTrait<descr, pred>;
 //===----------------------------------------------------------------------===//
 
 // These classes are used to define operation specific traits.
-class NativeOpTrait<string name> : NativeTrait<name, "Op">;
-class ParamNativeOpTrait<string prop, string params>
-    : ParamNativeTrait<prop, params, "Op">;
-class GenInternalOpTrait<string prop> : GenInternalTrait<prop, "Op">;
-class PredOpTrait<string descr, Pred pred> : PredTrait<descr, pred>;
+class NativeOpTrait<string name, list<Trait> traits = []>
+    : NativeTrait<name, "Op"> {
+  // Specify the list of traits that need to be verified before the verification
+  // of this NativeOpTrait.
+  list<Trait> dependentTraits = traits;
+}
+class ParamNativeOpTrait<string prop, string params,
+                         list<Trait> traits = []>
+    : ParamNativeTrait<prop, params, "Op"> {
+  // Specify the list of traits that need to be verified before the verification
+  // of this ParamNativeOpTrait.
+  list<Trait> dependentTraits = traits;
+}
+class GenInternalOpTrait<string prop, list<Trait> traits = []>
+    : GenInternalTrait<prop, "Op"> {
+  // Specify the list of traits that need to be verified before the verification
+  // of this GenInternalOpTrait.
+  list<Trait> dependentTraits = traits;
+}
+class PredOpTrait<string descr, Pred pred, list<Trait> traits = []>
+    : PredTrait<descr, pred> {
+  // Specify the list of traits that need to be verified before the verification
+  // of this PredOpTrait.
+  list<Trait> dependentTraits = traits;
+}
 
 // Op defines an affine scope.
 def AffineScope : NativeOpTrait<"AffineScope">;
@@ -2164,11 +2184,16 @@ class InterfaceTrait<string name> : NativeTrait<"", ""> {
 // OpInterfaceTrait corresponds to a specific 'OpInterface' class defined in
 // C++. The purpose to wrap around C++ symbol string with this class is to make
 // interfaces specified for ops in TableGen less alien and more integrated.
-class OpInterfaceTrait<string name, code verifyBody = [{}]>
+class OpInterfaceTrait<string name, code verifyBody = [{}],
+                       list<Trait> traits = []>
     : InterfaceTrait<name> {
   // Specify the body of the verification function. `$_op` will be replaced with
   // the operation being verified.
   code verify = verifyBody;
+
+  // Specify the list of traits that need to be verified before the verification
+  // of this OpInterfaceTrait.
+  list<Trait> dependentTraits = traits;
 }
 
 // This class represents a single, optionally static, interface method.

diff  --git a/mlir/lib/TableGen/Operator.cpp b/mlir/lib/TableGen/Operator.cpp
index 298f16f569e74..c9815955062b3 100644
--- a/mlir/lib/TableGen/Operator.cpp
+++ b/mlir/lib/TableGen/Operator.cpp
@@ -548,6 +548,23 @@ void Operator::populateOpStructure() {
     SmallPtrSet<const llvm::Init *, 32> traitSet;
     traits.reserve(traitSet.size());
 
+    // The declaration order of traits imply the verification order of traits.
+    // Some traits may require other traits to be verified first then they can
+    // do further verification based on those verified facts. If you see this
+    // error, fix the traits declaration order by checking the `dependentTraits`
+    // field.
+    auto verifyTraitValidity = [&](Record *trait) {
+      auto *dependentTraits = trait->getValueAsListInit("dependentTraits");
+      for (auto *traitInit : *dependentTraits)
+        if (traitSet.find(traitInit) == traitSet.end())
+          PrintFatalError(
+              def.getLoc(),
+              trait->getValueAsString("trait") + " requires " +
+                  cast<DefInit>(traitInit)->getDef()->getValueAsString(
+                      "trait") +
+                  " to precede it in traits list");
+    };
+
     std::function<void(llvm::ListInit *)> insert;
     insert = [&](llvm::ListInit *traitList) {
       for (auto *traitInit : *traitList) {
@@ -556,6 +573,11 @@ void Operator::populateOpStructure() {
           insert(def->getValueAsListInit("traits"));
           continue;
         }
+
+        // Verify if the trait has all the dependent traits declared before
+        // itself.
+        verifyTraitValidity(def);
+
         // Keep traits in the same order while skipping over duplicates.
         if (traitSet.insert(traitInit).second)
           traits.push_back(Trait::create(traitInit));

diff  --git a/mlir/test/mlir-tblgen/op-error.td b/mlir/test/mlir-tblgen/op-error.td
index 4be846b9a940f..a2eab1f08df28 100644
--- a/mlir/test/mlir-tblgen/op-error.td
+++ b/mlir/test/mlir-tblgen/op-error.td
@@ -9,6 +9,8 @@
 // RUN: not mlir-tblgen -gen-op-decls -I %S/../../include -DERROR9 %s 2>&1 | FileCheck --check-prefix=ERROR9 %s
 // RUN: not mlir-tblgen -gen-op-decls -I %S/../../include -DERROR10 %s 2>&1 | FileCheck --check-prefix=ERROR10 %s
 // RUN: not mlir-tblgen -gen-op-decls -I %S/../../include -DERROR11 %s 2>&1 | FileCheck --check-prefix=ERROR11 %s
+// RUN: not mlir-tblgen -gen-op-decls -I %S/../../include -DERROR12 %s 2>&1 | FileCheck --check-prefix=ERROR12 %s
+// RUN: not mlir-tblgen -gen-op-decls -I %S/../../include -DERROR13 %s 2>&1 | FileCheck --check-prefix=ERROR13 %s
 
 include "mlir/IR/OpBase.td"
 
@@ -104,3 +106,21 @@ def OpWithDuplicatedArgResultNames : Op<Test_Dialect, "default_value"> {
   let regions = (region AnyRegion:$target);
 }
 #endif
+
+#ifdef ERROR12
+def OpTraitA : NativeOpTrait<"OpTraitA"> {}
+def OpTraitB : NativeOpTrait<"OpTraitB", [OpTraitA]> {}
+
+// ERROR12: error: OpTraitB requires OpTraitA to precede it in traits list
+def OpTraitWithoutDependentTrait : Op<Test_Dialect, "default_value", [OpTraitB]> {}
+#endif
+
+#ifdef ERROR13
+def OpTraitA : NativeOpTrait<"OpTraitA"> {}
+def OpInterfaceB : OpInterface<"OpInterfaceB"> {
+  let dependentTraits = [OpTraitA];
+}
+
+// ERROR13: error: OpInterfaceB::Trait requires OpTraitA to precede it in traits list
+def OpInterfaceWithoutDependentTrait : Op<Test_Dialect, "default_value", [OpInterfaceB]> {}
+#endif


        


More information about the Mlir-commits mailing list