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:
@@ -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
|
Polymorphism only works for SSA value operands. Other operands have a fixed
|
||||||
operand kind.
|
operand kind.
|
||||||
|
|
||||||
.. autoclass:: TypeVar
|
.. autoclass:: cretonne.typevar.TypeVar
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
If multiple operands refer to the same type variable they will be required to
|
If multiple operands refer to the same type variable they will be required to
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from __future__ import absolute_import
|
|||||||
import re
|
import re
|
||||||
import math
|
import math
|
||||||
import importlib
|
import importlib
|
||||||
from collections import namedtuple, OrderedDict
|
from collections import OrderedDict
|
||||||
from .predicates import And
|
from .predicates import And
|
||||||
|
|
||||||
|
|
||||||
@@ -518,98 +518,6 @@ class BoolType(ScalarType):
|
|||||||
return 'BoolType(bits={})'.format(self.bits)
|
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.
|
# Defining instructions.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ This module defines the basic Cretonne instruction set that all targets
|
|||||||
support.
|
support.
|
||||||
"""
|
"""
|
||||||
from __future__ import absolute_import
|
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 .types import i8, f32, f64, b1
|
||||||
from .immediates import imm64, uimm8, ieee32, ieee64, immvector, intcc, floatcc
|
from .immediates import imm64, uimm8, ieee32, ieee64, immvector, intcc, floatcc
|
||||||
from . import entities
|
from . import entities
|
||||||
|
|||||||
98
meta/cretonne/typevar.py
Normal file
98
meta/cretonne/typevar.py
Normal 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
|
||||||
Reference in New Issue
Block a user