torch-mlir/include/npcomp/Dialect/Basicpy/BasicpyOps.td

297 lines
9.6 KiB
TableGen

//===- BasicPyOps.td - Basic Python ops --------------------*- tablegen -*-===//
//
// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef NPCOMP_DIALECT_BASICPY_BASICPY_OPS
#define NPCOMP_DIALECT_BASICPY_BASICPY_OPS
include "BasicpyDialect.td"
include "mlir/Interfaces/ControlFlowInterfaces.td"
include "mlir/Interfaces/SideEffectInterfaces.td"
include "mlir/IR/SymbolInterfaces.td"
//===----------------------------------------------------------------------===//
// Predicates
//===----------------------------------------------------------------------===//
def BoolOrI1Type : AnyTypeOf<[Basicpy_BoolType, I1], "Python bool or i1">;
//===----------------------------------------------------------------------===//
// Binary operation enum
// The name matches the operation name in the python AST ("Add", "Mult", etc).
//===----------------------------------------------------------------------===//
def BINOP_ADD : StrEnumAttrCase<"Add">;
def BINOP_BITAND : StrEnumAttrCase<"BitAnd">;
def BINOP_BITOR : StrEnumAttrCase<"BitOr">;
def BINOP_BITXOR : StrEnumAttrCase<"BitXor">;
def BINOP_DIV : StrEnumAttrCase<"Div">;
def BINOP_FLOORDIV : StrEnumAttrCase<"FloorDiv">;
def BINOP_LSHIFT : StrEnumAttrCase<"LShift">;
def BINOP_MATMULT : StrEnumAttrCase<"MatMult">;
def BINOP_MOD : StrEnumAttrCase<"Mod">;
def BINOP_MULT : StrEnumAttrCase<"Mult">;
def BINOP_RSHIFT : StrEnumAttrCase<"RShift">;
def BINOP_SUB : StrEnumAttrCase<"Sub">;
def BinaryOperationAttr : StrEnumAttr<
"BinaryOperation", "Operation for a binary expression", [
BINOP_ADD,
BINOP_BITAND,
BINOP_BITOR,
BINOP_BITXOR,
BINOP_DIV,
BINOP_FLOORDIV,
BINOP_LSHIFT,
BINOP_MATMULT,
BINOP_MOD,
BINOP_MULT,
BINOP_RSHIFT,
BINOP_SUB,
]> {
let cppNamespace = "::mlir::NPCOMP::Basicpy";
}
//===----------------------------------------------------------------------===//
// Comparison operation enum
// The name matches the operation name in the python AST ("Lt", "Gt", etc).
//===----------------------------------------------------------------------===//
def CMPOP_EQ : StrEnumAttrCase<"Eq">;
def CMPOP_GT : StrEnumAttrCase<"Gt">;
def CMPOP_GTE : StrEnumAttrCase<"GtE">;
def CMPOP_IN : StrEnumAttrCase<"In">;
def CMPOP_IS : StrEnumAttrCase<"Is">;
def CMPOP_ISNOT : StrEnumAttrCase<"IsNot">;
def CMPOP_LT : StrEnumAttrCase<"Lt">;
def CMPOP_LTE : StrEnumAttrCase<"LtE">;
def CMPOP_NEQ : StrEnumAttrCase<"NotEq">;
def CMPOP_NOTIN : StrEnumAttrCase<"NotIn">;
def CompareOperationAttr : StrEnumAttr<
"CompareOperation", "Comparison operator", [
CMPOP_EQ,
CMPOP_GT,
CMPOP_GTE,
CMPOP_IN,
CMPOP_IS,
CMPOP_ISNOT,
CMPOP_LT,
CMPOP_LTE,
CMPOP_NEQ,
CMPOP_NOTIN,
]> {
let cppNamespace = "::mlir::NPCOMP::Basicpy";
}
//===----------------------------------------------------------------------===//
// Ops
//===----------------------------------------------------------------------===//
def Basicpy_BinaryCompareOp : Basicpy_Op<"binary_compare", []> {
let summary = "Performs a comparison between two operands";
let description = [{
This op performs only one step of a potentially multi-step short
circuit comparison.
See: https://docs.python.org/3/reference/expressions.html#comparisons
}];
let arguments = (ins
AnyType:$left,
AnyType:$right,
CompareOperationAttr:$operation
);
let results = (outs
Basicpy_BoolType:$result
);
let assemblyFormat = "$left $operation $right attr-dict `:` type(operands)";
}
def Basicpy_BinaryExprOp : Basicpy_Op<"binary_expr", []> {
let summary = "Binary expression";
let description = [{
An expression between two operands as generated by the AST BinOp node.
}];
let arguments = (ins
AnyType:$left,
AnyType:$right,
BinaryOperationAttr:$operation
);
let results = (outs
AnyType:$result
);
let assemblyFormat = "$left $operation $right attr-dict `:` functional-type(operands, results)";
}
def Basicpy_BoolCastOp : Basicpy_Op<"bool_cast", [NoSideEffect]> {
let summary = "Casts between BoolType and i1";
let description = [{
When interfacing with lower level dialect or progressively lowering
the Python BoolType away, it is often necessary to cast between it and
i1, which is used to represent bool-ness at lower levels.
}];
let arguments = (ins BoolOrI1Type:$operand);
let results = (outs BoolOrI1Type:$result);
let assemblyFormat = "$operand attr-dict `:` type(operands) `->` type(results)";
}
def Basicpy_BoolConstantOp : Basicpy_Op<"bool_constant", [
ConstantLike, NoSideEffect]> {
let summary = "A boolean constant";
let description = [{
A constant of type !basicpy.BoolType that can take either an i1 value
of 0 (False) or 1 (True).
}];
let arguments = (ins I1Attr:$value);
let results = (outs
Basicpy_BoolType:$result
);
let assemblyFormat = "$value attr-dict";
}
def Basicpy_BytesConstantOp : Basicpy_Op<"bytes_constant", [
ConstantLike, NoSideEffect]> {
let summary = "Constant bytes value";
let description = [{
A bytes value of BytesType. The value is represented by a StringAttr.
}];
let arguments = (ins
StrAttr:$value
);
let results = (outs
Basicpy_BytesType:$result
);
let assemblyFormat = "$value attr-dict";
}
def Basicpy_ExecOp : Basicpy_Op<"exec", [
SingleBlockImplicitTerminator<"ExecDiscardOp">]> {
let summary = "Evaluates an expression being executed as a statement";
let description = [{
The result is discarded. Typically expressions are no-side-effect and can
be re-ordered as needed. Embedding one in an exec op ensures that its
placement in program order is preserved.
}];
let regions = (region SizedRegion<1>:$body);
let skipDefaultBuilders = 1;
let builders = [
OpBuilder<"OpBuilder &builder, OperationState &result">,
];
let extraClassDeclaration = [{
OpBuilder getBodyBuilder() {
Block* body = getBody(0);
return OpBuilder::atBlockEnd(body);
}
}];
}
def Basicpy_ExecDiscardOp : Basicpy_Op<"exec_discard", [
NoSideEffect, ReturnLike, Terminator]> {
let summary = "Terminator for an exec block";
let description = [{
Discards results and terminates an exec block.
}];
let arguments = (ins Variadic<AnyType>:$operands);
let assemblyFormat = "operands attr-dict `:` type(operands)";
}
def Basicpy_SlotObjectMakeOp : Basicpy_Op<"slot_object_make", [
NoSideEffect]> {
let summary = "Creates an instance of a SlotObject type";
let description = [{
SlotObjects are typically instances of built-in classes that have a fixed
number of slots. Unlike in standard python, the types of each slot are
tracked.
This op has a custom assembly form which can be used when valid that
omits the operand types (since they are equal to the types in the returned
slot object). Example:
%0 = basicpy.singleton : !basicpy.NoneType
%1 = basicpy.slot_object_make(%0) ->
!basicpy.SlotObject<slice, !basicpy.NoneType>
}];
let arguments = (ins
StrAttr:$className,
// TODO: Tighter constraints on allowable types.
Variadic<AnyType>:$slots
);
let results = (outs
Basicpy_SlotObjectType:$result
);
}
def Basicpy_SlotObjectGetOp : Basicpy_Op<"slot_object_get", [
NoSideEffect]> {
let summary = "Gets a slot from a slot object";
let description = [{
Gets a slot from a SlotObject.
Example:
%0 = basicpy.slot_object_make ...
%1 = basicpy.slot_object_get %0[1] : !basicpy.SlotObject<...>
}];
let arguments = (ins
Basicpy_SlotObjectType:$object,
IndexAttr:$index
);
let results = (outs
AnyType:$result
);
}
def Basicpy_StrConstantOp : Basicpy_Op<"str_constant", [
ConstantLike, NoSideEffect]> {
let summary = "Constant string value";
let description = [{
A string value of StrType. The value is represented by a StringAttr
that is UTF-8 encoded.
}];
let arguments = (ins
StrAttr:$value
);
let results = (outs
Basicpy_StrType:$result
);
let assemblyFormat = "$value attr-dict";
}
def Basicpy_SingletonOp : Basicpy_Op<"singleton", [
ConstantLike, NoSideEffect]> {
let summary = "Constant value for a singleton type";
let description = [{
Some types only have a single possible value, represented by the
SingletonAttr. This op allows creating constants of these types.
}];
let arguments = (ins);
let results = (outs
Basicpy_SingletonType:$result
);
let assemblyFormat = "attr-dict `:` type($result)";
}
def Basicpy_ToBooleanOp : Basicpy_Op<"to_boolean", [NoSideEffect]> {
let summary = "Evaluates an input to an i1 boolean value";
let description = [{
Applies the rules for interpreting a type as a boolean, returning an i1
indicating the truthiness of the operand. Since the output of this op
is intended to drive lower-level control flow, the i1 type is used (not
the user level BoolType).
}];
let arguments = (ins AnyType:$operand);
let results = (outs I1:$result);
let assemblyFormat = "$operand attr-dict `:` type($operand)";
}
def Basicpy_UnknownCastOp : Basicpy_Op<"unknown_cast", [NoSideEffect]> {
let summary = "Casts to and from the UnknownType";
let arguments = (ins AnyType:$input);
let results = (outs AnyType:$result);
let assemblyFormat = "operands attr-dict `:` type(operands) `->` type(results)";
}
#endif // NPCOMP_DIALECT_BASICPY_BASICPY_OPS