mirror of https://github.com/llvm/torch-mlir
Add string constants.
parent
869228e316
commit
f3829b1d4f
|
@ -21,11 +21,12 @@ namespace Basicpy {
|
|||
namespace BasicpyTypes {
|
||||
enum Kind {
|
||||
// Dialect types.
|
||||
UnknownType = TypeRanges::Basicpy,
|
||||
NoneType,
|
||||
BoolType,
|
||||
BoolType = TypeRanges::Basicpy,
|
||||
EllipsisType,
|
||||
NoneType,
|
||||
SlotObjectType,
|
||||
StrType,
|
||||
UnknownType,
|
||||
|
||||
// Dialect attributes.
|
||||
SingletonAttr,
|
||||
|
@ -37,28 +38,6 @@ namespace detail {
|
|||
struct SlotObjectTypeStorage;
|
||||
} // namespace detail
|
||||
|
||||
/// An unknown type that could be any supported python type.
|
||||
class UnknownType : public Type::TypeBase<UnknownType, Type> {
|
||||
public:
|
||||
using Base::Base;
|
||||
static bool kindof(unsigned kind) {
|
||||
return kind == BasicpyTypes::UnknownType;
|
||||
}
|
||||
static UnknownType get(MLIRContext *context) {
|
||||
return Base::get(context, BasicpyTypes::UnknownType);
|
||||
}
|
||||
};
|
||||
|
||||
/// The type of the Python `None` value.
|
||||
class NoneType : public Type::TypeBase<NoneType, Type> {
|
||||
public:
|
||||
using Base::Base;
|
||||
static bool kindof(unsigned kind) { return kind == BasicpyTypes::NoneType; }
|
||||
static NoneType get(MLIRContext *context) {
|
||||
return Base::get(context, BasicpyTypes::NoneType);
|
||||
}
|
||||
};
|
||||
|
||||
/// Python 'bool' type (can contain values True or False, corresponding to
|
||||
/// i1 constants of 0 or 1).
|
||||
class BoolType : public Type::TypeBase<BoolType, Type> {
|
||||
|
@ -82,6 +61,16 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// The type of the Python `None` value.
|
||||
class NoneType : public Type::TypeBase<NoneType, Type> {
|
||||
public:
|
||||
using Base::Base;
|
||||
static bool kindof(unsigned kind) { return kind == BasicpyTypes::NoneType; }
|
||||
static NoneType get(MLIRContext *context) {
|
||||
return Base::get(context, BasicpyTypes::NoneType);
|
||||
}
|
||||
};
|
||||
|
||||
class SlotObjectType : public Type::TypeBase<SlotObjectType, Type,
|
||||
detail::SlotObjectTypeStorage> {
|
||||
public:
|
||||
|
@ -101,6 +90,28 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// The type of the Python `str` values.
|
||||
class StrType : public Type::TypeBase<StrType, Type> {
|
||||
public:
|
||||
using Base::Base;
|
||||
static bool kindof(unsigned kind) { return kind == BasicpyTypes::StrType; }
|
||||
static StrType get(MLIRContext *context) {
|
||||
return Base::get(context, BasicpyTypes::StrType);
|
||||
}
|
||||
};
|
||||
|
||||
/// An unknown type that could be any supported python type.
|
||||
class UnknownType : public Type::TypeBase<UnknownType, Type> {
|
||||
public:
|
||||
using Base::Base;
|
||||
static bool kindof(unsigned kind) {
|
||||
return kind == BasicpyTypes::UnknownType;
|
||||
}
|
||||
static UnknownType get(MLIRContext *context) {
|
||||
return Base::get(context, BasicpyTypes::UnknownType);
|
||||
}
|
||||
};
|
||||
|
||||
#include "npcomp/Dialect/Basicpy/BasicpyOpsDialect.h.inc"
|
||||
|
||||
} // namespace Basicpy
|
||||
|
|
|
@ -38,11 +38,19 @@ class Basicpy_Op<string mnemonic, list<OpTrait> traits = []> :
|
|||
// Dialect types
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def Basicpy_UnknownType : DialectType<Basicpy_Dialect,
|
||||
CPred<"$_self.isa<::mlir::NPCOMP::Basicpy::UnknownType>()">,
|
||||
"Unknown type"> {
|
||||
def Basicpy_BoolType : DialectType<Basicpy_Dialect,
|
||||
CPred<"$_self.isa<::mlir::NPCOMP::Basicpy::BoolType>()">, "Bool type">,
|
||||
BuildableType<"$_builder.getType<::mlir::NPCOMP::Basicpy::BoolType>()"> {
|
||||
let typeDescription = [{
|
||||
An unknown type (for the current phase of processing).
|
||||
Type for 'True' and 'False' values.
|
||||
}];
|
||||
}
|
||||
|
||||
def Basicpy_EllipsisType : DialectType<Basicpy_Dialect,
|
||||
CPred<"$_self.isa<::mlir::NPCOMP::Basicpy::EllipsisType>()">, "Ellipsis type">,
|
||||
BuildableType<"$_builder.getType<::mlir::NPCOMP::Basicpy::EllipsisType>()"> {
|
||||
let typeDescription = [{
|
||||
Type of the Python 'Ellipsis' value.
|
||||
}];
|
||||
}
|
||||
|
||||
|
@ -54,14 +62,6 @@ def Basicpy_NoneType : DialectType<Basicpy_Dialect,
|
|||
}];
|
||||
}
|
||||
|
||||
def Basicpy_BoolType : DialectType<Basicpy_Dialect,
|
||||
CPred<"$_self.isa<::mlir::NPCOMP::Basicpy::BoolType>()">, "Bool type">,
|
||||
BuildableType<"$_builder.getType<::mlir::NPCOMP::Basicpy::BoolType>()"> {
|
||||
let typeDescription = [{
|
||||
Type for 'True' and 'False' values.
|
||||
}];
|
||||
}
|
||||
|
||||
def Basicpy_SlotObjectType : DialectType<Basicpy_Dialect,
|
||||
CPred<"$_self.isa<::mlir::NPCOMP::Basicpy::SlotObjectType>()">,
|
||||
"Slot object"> {
|
||||
|
@ -72,11 +72,19 @@ def Basicpy_SlotObjectType : DialectType<Basicpy_Dialect,
|
|||
}];
|
||||
}
|
||||
|
||||
def Basicpy_EllipsisType : DialectType<Basicpy_Dialect,
|
||||
CPred<"$_self.isa<::mlir::NPCOMP::Basicpy::EllipsisType>()">, "Ellipsis type">,
|
||||
BuildableType<"$_builder.getType<::mlir::NPCOMP::Basicpy::EllipsisType>()"> {
|
||||
def Basicpy_StrType : DialectType<Basicpy_Dialect,
|
||||
CPred<"$_self.isa<::mlir::NPCOMP::Basicpy::StrType>()">,"String type">,
|
||||
BuildableType<"$_builder.getType<::mlir::NPCOMP::Basicpy::StrType>()"> {
|
||||
let typeDescription = [{
|
||||
Type of the Python 'Ellipsis' value.
|
||||
Represents values of the python 'str' type.
|
||||
}];
|
||||
}
|
||||
|
||||
def Basicpy_UnknownType : DialectType<Basicpy_Dialect,
|
||||
CPred<"$_self.isa<::mlir::NPCOMP::Basicpy::UnknownType>()">,
|
||||
"Unknown type"> {
|
||||
let typeDescription = [{
|
||||
An unknown type (for the current phase of processing).
|
||||
}];
|
||||
}
|
||||
|
||||
|
|
|
@ -13,27 +13,6 @@ include "BasicpyDialect.td"
|
|||
include "mlir/Interfaces/SideEffectInterfaces.td"
|
||||
include "mlir/IR/SymbolInterfaces.td"
|
||||
|
||||
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)";
|
||||
}
|
||||
|
||||
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_BoolConstantOp : Basicpy_Op<"bool_constant", [
|
||||
ConstantLike, NoSideEffect]> {
|
||||
let summary = "A boolean constant";
|
||||
|
@ -92,4 +71,41 @@ def Basicpy_SlotObjectGetOp : Basicpy_Op<"slot_object_get", [
|
|||
);
|
||||
}
|
||||
|
||||
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_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
|
||||
|
|
|
@ -19,7 +19,8 @@ BasicpyDialect::BasicpyDialect(MLIRContext *context)
|
|||
#define GET_OP_LIST
|
||||
#include "npcomp/Dialect/Basicpy/BasicpyOps.cpp.inc"
|
||||
>();
|
||||
addTypes<EllipsisType, NoneType, BoolType, SlotObjectType, UnknownType>();
|
||||
addTypes<BoolType, EllipsisType, NoneType, SlotObjectType, StrType,
|
||||
UnknownType>();
|
||||
|
||||
// TODO: Make real ops for everything we need.
|
||||
allowUnknownOperations();
|
||||
|
@ -30,14 +31,12 @@ Type BasicpyDialect::parseType(DialectAsmParser &parser) const {
|
|||
if (parser.parseKeyword(&keyword))
|
||||
return Type();
|
||||
|
||||
if (keyword == "UnknownType")
|
||||
return UnknownType::get(getContext());
|
||||
if (keyword == "NoneType")
|
||||
return NoneType::get(getContext());
|
||||
if (keyword == "BoolType")
|
||||
return BoolType::get(getContext());
|
||||
if (keyword == "EllipsisType")
|
||||
return EllipsisType::get(getContext());
|
||||
if (keyword == "NoneType")
|
||||
return NoneType::get(getContext());
|
||||
if (keyword == "SlotObject") {
|
||||
StringRef className;
|
||||
if (parser.parseLess() || parser.parseKeyword(&className)) {
|
||||
|
@ -56,6 +55,10 @@ Type BasicpyDialect::parseType(DialectAsmParser &parser) const {
|
|||
return SlotObjectType::get(StringAttr::get(className, getContext()),
|
||||
slotTypes);
|
||||
}
|
||||
if (keyword == "StrType")
|
||||
return StrType::get(getContext());
|
||||
if (keyword == "UnknownType")
|
||||
return UnknownType::get(getContext());
|
||||
|
||||
parser.emitError(parser.getNameLoc(), "unknown basicpy type");
|
||||
return Type();
|
||||
|
@ -63,18 +66,15 @@ Type BasicpyDialect::parseType(DialectAsmParser &parser) const {
|
|||
|
||||
void BasicpyDialect::printType(Type type, DialectAsmPrinter &os) const {
|
||||
switch (type.getKind()) {
|
||||
case BasicpyTypes::UnknownType:
|
||||
os << "UnknownType";
|
||||
return;
|
||||
case BasicpyTypes::NoneType:
|
||||
os << "NoneType";
|
||||
return;
|
||||
case BasicpyTypes::BoolType:
|
||||
os << "BoolType";
|
||||
return;
|
||||
case BasicpyTypes::EllipsisType:
|
||||
os << "EllipsisType";
|
||||
return;
|
||||
case BasicpyTypes::NoneType:
|
||||
os << "NoneType";
|
||||
return;
|
||||
case BasicpyTypes::SlotObjectType: {
|
||||
auto slotObject = type.cast<SlotObjectType>();
|
||||
auto slotTypes = slotObject.getSlotTypes();
|
||||
|
@ -86,6 +86,12 @@ void BasicpyDialect::printType(Type type, DialectAsmPrinter &os) const {
|
|||
os << ">";
|
||||
return;
|
||||
}
|
||||
case BasicpyTypes::StrType:
|
||||
os << "StrType";
|
||||
return;
|
||||
case BasicpyTypes::UnknownType:
|
||||
os << "UnknownType";
|
||||
return;
|
||||
default:
|
||||
llvm_unreachable("unexpected 'basicpy' type kind");
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ def import_global(f):
|
|||
return f
|
||||
|
||||
|
||||
# CHECK: func @integer_constants
|
||||
# CHECK-LABEL: func @integer_constants
|
||||
@import_global
|
||||
def integer_constants():
|
||||
# CHECK: %[[A:.*]] = constant 100 : i64
|
||||
|
@ -20,7 +20,7 @@ def integer_constants():
|
|||
# CHECK: return %[[A_CAST]]
|
||||
return a
|
||||
|
||||
# CHECK: func @float_constants
|
||||
# CHECK-LABEL: func @float_constants
|
||||
@import_global
|
||||
def float_constants():
|
||||
# CHECK: %[[A:.*]] = constant 2.200000e+00 : f64
|
||||
|
@ -29,7 +29,7 @@ def float_constants():
|
|||
# CHECK: return %[[A_CAST]]
|
||||
return a
|
||||
|
||||
# CHECK: func @bool_true_constant
|
||||
# CHECK-LABEL: func @bool_true_constant
|
||||
@import_global
|
||||
def bool_true_constant():
|
||||
# CHECK: %[[A:.*]] = basicpy.bool_constant 1
|
||||
|
@ -37,10 +37,27 @@ def bool_true_constant():
|
|||
a = True
|
||||
return a
|
||||
|
||||
# CHECK: func @bool_false_constant
|
||||
# CHECK-LABEL: func @bool_false_constant
|
||||
@import_global
|
||||
def bool_false_constant():
|
||||
# CHECK: %[[A:.*]] = basicpy.bool_constant 0
|
||||
# CHECK: basicpy.unknown_cast %[[A]]
|
||||
a = False
|
||||
return a
|
||||
|
||||
# CHECK-LABEL: func @string_constant
|
||||
@import_global
|
||||
def string_constant():
|
||||
# CHECK: %[[A:.*]] = basicpy.str_constant "foobar"
|
||||
# CHECK: basicpy.unknown_cast %[[A]]
|
||||
a = "foobar"
|
||||
return a
|
||||
|
||||
# CHECK-LABEL: func @joined_string_constant
|
||||
@import_global
|
||||
def joined_string_constant():
|
||||
# CHECK: %[[A:.*]] = basicpy.str_constant "I am still here"
|
||||
# CHECK: basicpy.unknown_cast %[[A]]
|
||||
a = "I am" " still here"
|
||||
return a
|
||||
|
||||
|
|
|
@ -167,7 +167,7 @@ class FunctionDefImporter(BaseNodeVisitor):
|
|||
ir_h = self.fctx.ir_h
|
||||
expr = ExpressionImporter(self.fctx)
|
||||
expr.visit(ast_node.value)
|
||||
casted = ir_h.basicpy_unknown_cast(ir_h.basicpy_UnknownType,
|
||||
casted = ir_h.basicpy_unknown_cast_op(ir_h.basicpy_UnknownType,
|
||||
expr.value).result
|
||||
ir_h.return_op([casted])
|
||||
|
||||
|
@ -208,6 +208,8 @@ class ExpressionImporter(BaseNodeVisitor):
|
|||
self.value = ir_h.basicpy_bool_constant_op(False).result
|
||||
else:
|
||||
self.fctx.abort("unknown named constant '%r'" % (ast_node.value,))
|
||||
elif isinstance(ast_node, ast.Str):
|
||||
self.value = ir_h.basicpy_str_constant_op(ast_node.s).result
|
||||
else:
|
||||
self.fctx.abort("unknown constant type %s" %
|
||||
(ast_node.__class__.__name__))
|
||||
|
|
|
@ -47,9 +47,6 @@ class DialectHelper(_BaseDialectHelper):
|
|||
|
||||
"""
|
||||
|
||||
def basicpy_unknown_cast(self, result_type, operand):
|
||||
return self.op("basicpy.unknown_cast", [result_type], [operand])
|
||||
|
||||
def basicpy_bool_constant_op(self, value):
|
||||
c = self.context
|
||||
ival = 1 if value else 0
|
||||
|
@ -57,7 +54,7 @@ class DialectHelper(_BaseDialectHelper):
|
|||
"value": c.integer_attr(self.i1_type, ival)
|
||||
})
|
||||
return self.op("basicpy.bool_constant", [self.basicpy_BoolType], [], attrs)
|
||||
|
||||
|
||||
def basicpy_singleton_op(self, singleton_type):
|
||||
return self.op("basicpy.singleton", [singleton_type], [])
|
||||
|
||||
|
@ -70,6 +67,16 @@ class DialectHelper(_BaseDialectHelper):
|
|||
return self.op("basicpy.slot_object_make", [object_type], slot_values,
|
||||
attrs)
|
||||
|
||||
def basicpy_str_constant_op(self, value):
|
||||
c = self.context
|
||||
attrs = c.dictionary_attr({
|
||||
"value": c.string_attr(value.encode("utf-8"))
|
||||
})
|
||||
return self.op("basicpy.str_constant", [self.basicpy_StrType], [], attrs)
|
||||
|
||||
def basicpy_unknown_cast_op(self, result_type, operand):
|
||||
return self.op("basicpy.unknown_cast", [result_type], [operand])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import doctest
|
||||
|
|
|
@ -21,16 +21,6 @@ public:
|
|||
static void bind(py::module m) {
|
||||
py::class_<BasicpyDialectHelper, PyDialectHelper>(m, "BasicpyDialectHelper")
|
||||
.def(py::init<std::shared_ptr<PyContext>>())
|
||||
.def_property_readonly("basicpy_UnknownType",
|
||||
[](BasicpyDialectHelper &self) -> PyType {
|
||||
return Basicpy::UnknownType::get(
|
||||
&self.context->context);
|
||||
})
|
||||
.def_property_readonly("basicpy_NoneType",
|
||||
[](BasicpyDialectHelper &self) -> PyType {
|
||||
return Basicpy::NoneType::get(
|
||||
&self.context->context);
|
||||
})
|
||||
.def_property_readonly("basicpy_BoolType",
|
||||
[](BasicpyDialectHelper &self) -> PyType {
|
||||
return Basicpy::BoolType::get(
|
||||
|
@ -41,6 +31,11 @@ public:
|
|||
return Basicpy::EllipsisType::get(
|
||||
&self.context->context);
|
||||
})
|
||||
.def_property_readonly("basicpy_NoneType",
|
||||
[](BasicpyDialectHelper &self) -> PyType {
|
||||
return Basicpy::NoneType::get(
|
||||
&self.context->context);
|
||||
})
|
||||
.def("basicpy_SlotObject_type",
|
||||
[](BasicpyDialectHelper &self, std::string className,
|
||||
py::args pySlotTypes) -> PyType {
|
||||
|
@ -53,6 +48,16 @@ public:
|
|||
return Basicpy::SlotObjectType::get(classNameAttr, slotTypes);
|
||||
},
|
||||
py::arg("className"))
|
||||
.def_property_readonly("basicpy_StrType",
|
||||
[](BasicpyDialectHelper &self) -> PyType {
|
||||
return Basicpy::StrType::get(
|
||||
&self.context->context);
|
||||
})
|
||||
.def_property_readonly("basicpy_UnknownType",
|
||||
[](BasicpyDialectHelper &self) -> PyType {
|
||||
return Basicpy::UnknownType::get(
|
||||
&self.context->context);
|
||||
})
|
||||
.def("basicpy_slot_object_get_op",
|
||||
[](BasicpyDialectHelper &self, PyValue slotObject,
|
||||
unsigned index) -> PyOperationRef {
|
||||
|
|
Loading…
Reference in New Issue