[doc] Generate more readable description for operands

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
This commit is contained in:
Lei Zhang 2019-01-30 05:57:39 -08:00 committed by jpienaar
parent 994111238b
commit 18219caeb2
7 changed files with 34 additions and 28 deletions

View 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,
// a 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

View 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

View 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:

View 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)

View 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}}
}
// -----

View 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);
}

View 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";