Add bool constants.

pull/1/head
Stella Laurenzo 2020-06-07 15:15:19 -07:00
parent 8280b86c05
commit 869228e316
10 changed files with 93 additions and 13 deletions

View File

@ -23,6 +23,7 @@ enum Kind {
// Dialect types.
UnknownType = TypeRanges::Basicpy,
NoneType,
BoolType,
EllipsisType,
SlotObjectType,
@ -58,6 +59,17 @@ public:
}
};
/// Python 'bool' type (can contain values True or False, corresponding to
/// i1 constants of 0 or 1).
class BoolType : public Type::TypeBase<BoolType, Type> {
public:
using Base::Base;
static bool kindof(unsigned kind) { return kind == BasicpyTypes::BoolType; }
static BoolType get(MLIRContext *context) {
return Base::get(context, BasicpyTypes::BoolType);
}
};
/// The type of the Python `Ellipsis` value.
class EllipsisType : public Type::TypeBase<EllipsisType, Type> {
public:

View File

@ -46,6 +46,22 @@ def Basicpy_UnknownType : DialectType<Basicpy_Dialect,
}];
}
def Basicpy_NoneType : DialectType<Basicpy_Dialect,
CPred<"$_self.isa<::mlir::NPCOMP::Basicpy::NoneType>()">, "None type">,
BuildableType<"$_builder.getType<::mlir::NPCOMP::Basicpy::NoneType>()"> {
let typeDescription = [{
Type of the Python 'None' value.
}];
}
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"> {
@ -56,14 +72,6 @@ def Basicpy_SlotObjectType : DialectType<Basicpy_Dialect,
}];
}
def Basicpy_NoneType : DialectType<Basicpy_Dialect,
CPred<"$_self.isa<::mlir::NPCOMP::Basicpy::NoneType>()">, "None type">,
BuildableType<"$_builder.getType<::mlir::NPCOMP::Basicpy::NoneType>()"> {
let typeDescription = [{
Type of the Python 'None' value.
}];
}
def Basicpy_EllipsisType : DialectType<Basicpy_Dialect,
CPred<"$_self.isa<::mlir::NPCOMP::Basicpy::EllipsisType>()">, "Ellipsis type">,
BuildableType<"$_builder.getType<::mlir::NPCOMP::Basicpy::EllipsisType>()"> {

View File

@ -34,6 +34,20 @@ def Basicpy_SingletonOp : Basicpy_Op<"singleton", [
let assemblyFormat = "attr-dict `:` type($result)";
}
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_SlotObjectMakeOp : Basicpy_Op<"slot_object_make", [
NoSideEffect]> {
let summary = "Creates an instance of a SlotObject type";

View File

@ -19,7 +19,7 @@ BasicpyDialect::BasicpyDialect(MLIRContext *context)
#define GET_OP_LIST
#include "npcomp/Dialect/Basicpy/BasicpyOps.cpp.inc"
>();
addTypes<EllipsisType, NoneType, SlotObjectType, UnknownType>();
addTypes<EllipsisType, NoneType, BoolType, SlotObjectType, UnknownType>();
// TODO: Make real ops for everything we need.
allowUnknownOperations();
@ -34,6 +34,8 @@ Type BasicpyDialect::parseType(DialectAsmParser &parser) const {
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 == "SlotObject") {
@ -67,6 +69,9 @@ void BasicpyDialect::printType(Type type, DialectAsmPrinter &os) const {
case BasicpyTypes::NoneType:
os << "NoneType";
return;
case BasicpyTypes::BoolType:
os << "BoolType";
return;
case BasicpyTypes::EllipsisType:
os << "EllipsisType";
return;

View File

@ -8,6 +8,7 @@ def import_global(f):
fe.import_global_function(f)
print("// -----")
print(fe.ir_module.to_asm())
return f
# CHECK: func @integer_constants
@ -27,3 +28,19 @@ def float_constants():
# CHECK: %[[A_CAST:.*]] = basicpy.unknown_cast %[[A]] : f64 -> !basicpy.UnknownType
# CHECK: return %[[A_CAST]]
return a
# CHECK: func @bool_true_constant
@import_global
def bool_true_constant():
# CHECK: %[[A:.*]] = basicpy.bool_constant 1
# CHECK: basicpy.unknown_cast %[[A]]
a = True
return a
# CHECK: 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

View File

@ -35,7 +35,7 @@ config.substitutions.append(('%shlibext', config.llvm_shlib_ext))
config.substitutions.append(('%PYTHON', config.python_executable))
llvm_config.with_system_environment(
['HOME', 'INCLUDE', 'LIB', 'TMP', 'TEMP'])
['HOME', 'INCLUDE', 'LIB', 'NPCOMP_DEBUG', 'TMP', 'TEMP'])
llvm_config.use_default_substitutions()

View File

@ -64,7 +64,8 @@ class ImportFrontend:
# Define the function.
# TODO: Much more needs to be done here (arg/result mapping, etc)
logging.debug("Importing global function {}:\n{}", ast_fd.name,
logging.debug(":::::::")
logging.debug("::: Importing global function {}:\n{}", ast_fd.name,
ast.dump(ast_fd, include_attributes=True))
h.builder.set_file_line_col(filename_ident, ast_fd.lineno,
ast_fd.col_offset)
@ -181,7 +182,7 @@ class ExpressionImporter(BaseNodeVisitor):
def visit(self, node):
super().visit(node)
assert self.value, ("ExpressionImporter did not assign a value (%r)" %
(node,))
(ast.dump(node),))
def visit_Constant(self, ast_node):
ir_c = self.fctx.ir_c
@ -200,6 +201,13 @@ class ExpressionImporter(BaseNodeVisitor):
else:
self.fctx.abort("unsupported numeric constant type: %r" % (nval,))
self.value = ir_h.constant_op(ir_type, ir_attr).result
elif isinstance(ast_node, ast.NameConstant):
if ast_node.value is True:
self.value = ir_h.basicpy_bool_constant_op(True).result
elif ast_node.value is False:
self.value = ir_h.basicpy_bool_constant_op(False).result
else:
self.fctx.abort("unknown named constant '%r'" % (ast_node.value,))
else:
self.fctx.abort("unknown constant type %s" %
(ast_node.__class__.__name__))

View File

@ -2,10 +2,13 @@
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
import os
import string
import sys
_ENABLED = False
__all__ = ["debug"]
_ENABLED = "NPCOMP_DEBUG" in os.environ
_formatter = string.Formatter()

View File

@ -50,6 +50,14 @@ 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
attrs = c.dictionary_attr({
"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], [])

View File

@ -31,6 +31,11 @@ public:
return Basicpy::NoneType::get(
&self.context->context);
})
.def_property_readonly("basicpy_BoolType",
[](BasicpyDialectHelper &self) -> PyType {
return Basicpy::BoolType::get(
&self.context->context);
})
.def_property_readonly("basicpy_EllipsisType",
[](BasicpyDialectHelper &self) -> PyType {
return Basicpy::EllipsisType::get(