forked from OSchip/llvm-project
[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:
parent
994111238b
commit
18219caeb2
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
|
||||
// -----
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 << "«unnamed»: ";
|
||||
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 << "«unnamed»: ";
|
||||
else
|
||||
os << "`" << name << "`: ";
|
||||
os << op.getResultType(i).getTableGenDefName();
|
||||
os << "\n";
|
||||
os << op.getResultType(i).getDescription() << "\n";
|
||||
}
|
||||
|
||||
os << "\n";
|
||||
|
|
Loading…
Reference in New Issue