[doc] Generate more readable description for operands
authorLei Zhang <antiagainst@google.com>
Wed, 30 Jan 2019 13:57:39 +0000 (05:57 -0800)
committerjpienaar <jpienaar@google.com>
Fri, 29 Mar 2019 23:01:38 +0000 (16:01 -0700)
This CL mandated TypeConstraint and Type to provide descriptions and fixed
various subclasses and definitions to provide so. The purpose is to enforce
good documentation; using empty string as the default just invites oversight.

PiperOrigin-RevId: 231579629

mlir/include/mlir/IR/op_base.td
mlir/include/mlir/StandardOps/standard_ops.td
mlir/include/mlir/TableGen/Type.h
mlir/lib/TableGen/Type.cpp
mlir/test/IR/invalid-ops.mlir
mlir/test/mlir-tblgen/one-op-one-result.td
mlir/tools/mlir-tblgen/OpDocGen.cpp

index 3958d6e96eadd94e531d05fc1fe1a890df99ec4f..ebe60087a79040e554254c0cd7f7bd37515853ec 100644 (file)
@@ -91,17 +91,17 @@ def IsStaticShapeTensorTypePred :
 
 // A constraint on types.  This can be used to check the validity of
 // instruction arguments.
-class TypeConstraint<Pred condition, string descr = ""> {
+class TypeConstraint<Pred condition, string descr> {
   // The predicates that this type satisfies.
   // Format: {0} will be expanded to the type.
   Pred predicate = condition;
-  // User-readable description used, e.g., for error reporting.  If empty, a
-  // generic message will be used instead.
+  // User-readable description used, e.g., for error reporting.  If empty,
+  // generic message will be used instead.
   string description = descr;
 }
 
 // A type, carries type constraints, but accepts any type by default.
-class Type<Pred condition = CPred<"true">, string descr = "">
+class Type<Pred condition, string descr = "">
     : TypeConstraint<condition, descr>;
 
 // A type that can be constructed using MLIR::Builder.
@@ -117,7 +117,7 @@ class BuildableType<code builder> {
 }
 
 // Integer types.
-class IntegerBase<CPred pred, string descr = ?> : Type<pred, descr>;
+class IntegerBase<CPred pred, string descr> : Type<pred, descr>;
 
 // Any integer type irrespective of its width.
 def Integer : IntegerBase<CPred<"{0}.isa<IntegerType>()">, "integer">;
@@ -127,7 +127,8 @@ def Index : IntegerBase<CPred<"{0}.isa<IndexType>()">, "index">;
 
 // Integer type of a specific width.
 class I<int width>
-    : IntegerBase<CPred<"{0}.isInteger(" # width # ")">, "i" # width>,
+    : IntegerBase<CPred<"{0}.isInteger(" # width # ")">,
+                  width # "-bit integer">,
       BuildableType<"getIntegerType(" # width # ")"> {
   int bitwidth = width;
 }
@@ -135,14 +136,15 @@ def I1  : I<1>;
 def I32 : I<32>;
 
 // Floating point types.
-class FloatBase<CPred pred, string descr = ?> : Type<pred, descr>;
+class FloatBase<CPred pred, string descr> : Type<pred, descr>;
 
 // Any float type irrespective of its width.
-def Float : FloatBase<CPred<"{0}.isa<FloatType>()">, "floating point">;
+def Float : FloatBase<CPred<"{0}.isa<FloatType>()">, "floating-point">;
 
 // Float type of a specific width.
 class F<int width>
-    : FloatBase<CPred<"{0}.isF" # width # "()">, "f" # width>,
+    : FloatBase<CPred<"{0}.isF" # width # "()">,
+                width # "-bit float">,
       BuildableType<"getF" # width # "Type()"> {
   int bitwidth = width;
 }
@@ -156,8 +158,8 @@ class ContainerType<Type etype, Pred containerPred, code elementTypeCall,
     // element into the element type checker.
     Type<AllOf<[containerPred,
                 SubstLeaves<"{0}", !cast<string>(elementTypeCall),
-                           etype.predicate>]>,
-        descr # "<" # etype.description # ">" > {
+                etype.predicate>]>,
+         descr # " of " # etype.description # " values"> {
   // The type of elements in the container.
   Type elementType = etype;
 
@@ -199,7 +201,7 @@ def StaticShapeTensor
 class TypedTensor<Type t>
     : ContainerType<t, Tensor.predicate,
                     "{0}.cast<TensorType>().getElementType()",
-                   "tensor">;
+                    "tensor">;
 
 def F32Tensor : TypedTensor<F32>;
 
@@ -212,7 +214,7 @@ def IntegerLike : TypeConstraint<AnyOf<[Integer.predicate, Index.predicate,
 // Type constraint for float-like types: floats, vectors or tensors thereof.
 def FloatLike : TypeConstraint<AnyOf<[Float.predicate,
         TypedVector<Float>.predicate, TypedTensor<Float>.predicate]>,
-    "float-like">;
+    "floating-point-like">;
 
 //===----------------------------------------------------------------------===//
 // Attributes
index edf92c23d258386cb1d264f4eb018e7723ee46c4..478c3e47e9b09c8863290b4466e815551ae78938 100644 (file)
@@ -28,7 +28,7 @@
 include "mlir/IR/op_base.td"
 #endif // OP_BASE
 
-def AnyType : Type;
+def AnyType : Type<CPred<"true">, "any type">;
 
 // Base class for standard arithmetic operations.  Requires operands and
 // results to be of the same type, but does not constrain them to specific
index b905eacddbd32ae2f87111386f513cc5001c9f7d..b564240cca70c4abb5288df0f9a44f878fbde70e 100644 (file)
@@ -50,8 +50,8 @@ public:
   // be substituted with an expression returning an mlir::Type.
   std::string getConditionTemplate() const;
 
-  // Returns the user-readable description of the constraint.  If the
-  // description is not provided, returns an empty string.
+  // Returns the user-readable description of the constraint. If the description
+  // is not provided, returns the TableGen def name.
   StringRef getDescription() const;
 
 protected:
index 0c5def6d6219fa41bf79af18a151f3572b9cbaca..7042e95ef0d3027d2601dc4150e4cbfd0ca4413e 100644 (file)
@@ -44,12 +44,10 @@ std::string tblgen::TypeConstraint::getConditionTemplate() const {
 }
 
 llvm::StringRef tblgen::TypeConstraint::getDescription() const {
-  const static auto fieldName = "description";
-  auto *val = def.getValue(fieldName);
-  if (!val)
-    return "";
-
-  return def.getValueAsString(fieldName);
+  auto doc = def.getValueAsString("description");
+  if (doc.empty())
+    return def.getName();
+  return doc;
 }
 
 tblgen::TypeConstraint::TypeConstraint(const llvm::DefInit &init)
index 5fa9cb9f95613ec75e513260dc9b381090e1ce0e..9097d4016135be158613145ff145cfa3d98452e7 100644 (file)
@@ -173,12 +173,19 @@ func @func_with_ops(f32) {
   %sf = addf{%a, %a} : f32  // expected-error {{invalid operand}}
 }
 
+// -----
+
+func @func_with_ops(f32) {
+^bb0(%a : f32):
+  // expected-error@+1 {{'addi' op operand #0 must be integer-like}}
+  %sf = addi %a, %a : f32
+}
 
 // -----
 
 func @func_with_ops(i32) {
 ^bb0(%a : i32):
-  %sf = addf %a, %a : i32  // expected-error {{'addf' op operand #0 must be float-like}}
+  %sf = addf %a, %a : i32  // expected-error {{'addf' op operand #0 must be floating-point-like}}
 }
 
 // -----
index b3581a7fa0c8918165efa9eda4d461d0a7759d8a..44fc1ea437ab00413e776fce3669a7b38cdba4a1 100644 (file)
@@ -11,7 +11,7 @@ def Y_Const_Attr {
 }
 
 // Define ops to rewrite.
-def T1: Type;
+def T1: Type<CPred<"true">, "T1">;
 def X_AddOp : Op<"x.add"> {
   let arguments = (ins T1, T1);
 }
index 7dbe860d00157f7f79258b337d86e51b688b25f0..fafe45b8c60cd6fd71cc62e13eed4fea60c06e81 100644 (file)
@@ -33,6 +33,7 @@ using namespace llvm;
 using namespace mlir;
 
 using mlir::tblgen::Operator;
+using mlir::tblgen::Type;
 
 // Emit the description by aligning the text to the left per line (e.g.,
 // removing the minimum indentation across the block).
@@ -105,8 +106,7 @@ static void emitOpDoc(const RecordKeeper &recordKeeper, raw_ostream &os) {
         os << "`" << operand.name->getAsUnquotedString() << "`: ";
       else
         os << "&laquo;unnamed&raquo;: ";
-      os << operand.defInit->getAsUnquotedString();
-      os << "\n";
+      os << Type(operand.defInit).getDescription() << "\n";
     }
 
     // Emit attributes.
@@ -131,8 +131,7 @@ static void emitOpDoc(const RecordKeeper &recordKeeper, raw_ostream &os) {
         os << "&laquo;unnamed&raquo;: ";
       else
         os << "`" << name << "`: ";
-      os << op.getResultType(i).getTableGenDefName();
-      os << "\n";
+      os << op.getResultType(i).getDescription() << "\n";
     }
 
     os << "\n";