Move TypeVar and TypeSet into their own Python package.

These classes are not very entangled with the rest of __init__, and
we'll be expanding them a bit.
This commit is contained in:
Jakob Stoklund Olesen
2016-09-27 10:53:53 -07:00
parent d915718526
commit b06668aa8a
4 changed files with 102 additions and 95 deletions

View File

@@ -96,7 +96,7 @@ instances that refer to a *type variable* instead of a concrete value type.
Polymorphism only works for SSA value operands. Other operands have a fixed
operand kind.
.. autoclass:: TypeVar
.. autoclass:: cretonne.typevar.TypeVar
:members:
If multiple operands refer to the same type variable they will be required to

View File

@@ -8,7 +8,7 @@ from __future__ import absolute_import
import re
import math
import importlib
from collections import namedtuple, OrderedDict
from collections import OrderedDict
from .predicates import And
@@ -518,98 +518,6 @@ class BoolType(ScalarType):
return 'BoolType(bits={})'.format(self.bits)
# Parametric polymorphism.
#: A `TypeSet` represents a set of types. We don't allow arbitrary subsets of
#: types, but use a parametrized approach instead.
#: This is represented as a named tuple so it can be used as a dictionary key.
TypeSet = namedtuple(
'TypeSet', [
'allow_scalars',
'allow_simd',
'base',
'all_ints',
'all_floats',
'all_bools'])
class TypeVar(object):
"""
Type variables can be used in place of concrete types when defining
instructions. This makes the instructions *polymorphic*.
A type variable is restricted to vary over a subset of the value types.
This subset is specified by a set of flags that control the permitted base
types and whether the type variable can assume scalar or vector types, or
both.
:param name: Short name of type variable used in instruction descriptions.
:param doc: Documentation string.
:param base: Single base type or list of base types. Use this to specify an
exact set of base types if the general categories below are not good
enough.
:param ints: Allow all integer base types.
:param floats: Allow all floating point base types.
:param bools: Allow all boolean base types.
:param scalars: Allow type variable to assume scalar types.
:param simd: Allow type variable to assume vector types.
"""
def __init__(
self, name, doc, base=None,
ints=False, floats=False, bools=False,
scalars=True, simd=False,
derived_func=None):
self.name = name
self.__doc__ = doc
self.base = base
self.is_derived = isinstance(base, TypeVar)
if self.is_derived:
assert derived_func
self.derived_func = derived_func
self.name = '{}({})'.format(derived_func, base.name)
else:
self.type_set = TypeSet(
allow_scalars=scalars,
allow_simd=simd,
base=base,
all_ints=ints,
all_floats=floats,
all_bools=bools)
def __str__(self):
return "`{}`".format(self.name)
def lane_of(self):
"""
Return a derived type variable that is the scalar lane type of this
type variable.
When this type variable assumes a scalar type, the derived type will be
the same scalar type.
"""
return TypeVar(None, None, base=self, derived_func='LaneOf')
def as_bool(self):
"""
Return a derived type variable that has the same vector geometry as
this type variable, but with boolean lanes. Scalar types map to `b1`.
"""
return TypeVar(None, None, base=self, derived_func='AsBool')
def operand_kind(self):
# When a `TypeVar` object is used to describe the type of an `Operand`
# in an instruction definition, the kind of that operand is an SSA
# value.
return value
def free_typevar(self):
if isinstance(self.base, TypeVar):
return self.base
else:
return self
# Defining instructions.

View File

@@ -5,7 +5,8 @@ This module defines the basic Cretonne instruction set that all targets
support.
"""
from __future__ import absolute_import
from . import TypeVar, Operand, Instruction, InstructionGroup, variable_args
from . import Operand, Instruction, InstructionGroup, variable_args
from .typevar import TypeVar
from .types import i8, f32, f64, b1
from .immediates import imm64, uimm8, ieee32, ieee64, immvector, intcc, floatcc
from . import entities

98
meta/cretonne/typevar.py Normal file
View File

@@ -0,0 +1,98 @@
"""
Type variables for Parametric polymorphism.
Cretonne instructions and instruction transformations can be specified to be
polymorphic by using type variables.
"""
from __future__ import absolute_import
from collections import namedtuple
from . import value
#: A `TypeSet` represents a set of types. We don't allow arbitrary subsets of
#: types, but use a parametrized approach instead.
#: This is represented as a named tuple so it can be used as a dictionary key.
TypeSet = namedtuple(
'TypeSet', [
'allow_scalars',
'allow_simd',
'base',
'all_ints',
'all_floats',
'all_bools'])
class TypeVar(object):
"""
Type variables can be used in place of concrete types when defining
instructions. This makes the instructions *polymorphic*.
A type variable is restricted to vary over a subset of the value types.
This subset is specified by a set of flags that control the permitted base
types and whether the type variable can assume scalar or vector types, or
both.
:param name: Short name of type variable used in instruction descriptions.
:param doc: Documentation string.
:param base: Single base type or list of base types. Use this to specify an
exact set of base types if the general categories below are not good
enough.
:param ints: Allow all integer base types.
:param floats: Allow all floating point base types.
:param bools: Allow all boolean base types.
:param scalars: Allow type variable to assume scalar types.
:param simd: Allow type variable to assume vector types.
"""
def __init__(
self, name, doc, base=None,
ints=False, floats=False, bools=False,
scalars=True, simd=False,
derived_func=None):
self.name = name
self.__doc__ = doc
self.base = base
self.is_derived = isinstance(base, TypeVar)
if self.is_derived:
assert derived_func
self.derived_func = derived_func
self.name = '{}({})'.format(derived_func, base.name)
else:
self.type_set = TypeSet(
allow_scalars=scalars,
allow_simd=simd,
base=base,
all_ints=ints,
all_floats=floats,
all_bools=bools)
def __str__(self):
return "`{}`".format(self.name)
def lane_of(self):
"""
Return a derived type variable that is the scalar lane type of this
type variable.
When this type variable assumes a scalar type, the derived type will be
the same scalar type.
"""
return TypeVar(None, None, base=self, derived_func='LaneOf')
def as_bool(self):
"""
Return a derived type variable that has the same vector geometry as
this type variable, but with boolean lanes. Scalar types map to `b1`.
"""
return TypeVar(None, None, base=self, derived_func='AsBool')
def operand_kind(self):
# When a `TypeVar` object is used to describe the type of an `Operand`
# in an instruction definition, the kind of that operand is an SSA
# value.
return value
def free_typevar(self):
if isinstance(self.base, TypeVar):
return self.base
else:
return self