Browse Source
We want to separate the Python classes that make up the DSL used to define the Cretonne language from the concrete definitions. - cdsl.types defines the ValueType class hierarchy. - base.types defines the concrete types.pull/3/head
Jakob Stoklund Olesen
8 years ago
11 changed files with 210 additions and 202 deletions
@ -0,0 +1 @@ |
|||
"""Definitions for the base Cretonne language.""" |
@ -1,8 +1,8 @@ |
|||
""" |
|||
The cretonne.types module predefines all the Cretonne scalar types. |
|||
The base.types module predefines all the Cretonne scalar types. |
|||
""" |
|||
from __future__ import absolute_import |
|||
from . import ScalarType, IntType, FloatType, BoolType |
|||
from cdsl.types import ScalarType, IntType, FloatType, BoolType |
|||
|
|||
#: Boolean. |
|||
b1 = ScalarType( |
@ -0,0 +1,6 @@ |
|||
""" |
|||
Cretonne DSL classes. |
|||
|
|||
This module defines the classes that are used to define Cretonne instructions |
|||
and other entitties. |
|||
""" |
@ -0,0 +1,160 @@ |
|||
"""Cretonne ValueType hierarchy""" |
|||
from __future__ import absolute_import |
|||
import math |
|||
|
|||
|
|||
# ValueType instances (i8, i32, ...) are provided in the cretonne.types module. |
|||
class ValueType(object): |
|||
""" |
|||
A concrete SSA value type. |
|||
|
|||
All SSA values have a type that is described by an instance of `ValueType` |
|||
or one of its subclasses. |
|||
""" |
|||
|
|||
# Map name -> ValueType. |
|||
_registry = dict() # type: Dict[str, ValueType] |
|||
|
|||
# List of all the scalar types. |
|||
all_scalars = list() # type: List[ValueType] |
|||
|
|||
def __init__(self, name, membytes, doc): |
|||
# type: (str, int, str) -> None |
|||
self.name = name |
|||
self.membytes = membytes |
|||
self.__doc__ = doc |
|||
assert name not in ValueType._registry |
|||
ValueType._registry[name] = self |
|||
|
|||
def __str__(self): |
|||
# type: () -> str |
|||
return self.name |
|||
|
|||
def free_typevar(self): |
|||
return None |
|||
|
|||
@staticmethod |
|||
def by_name(name): |
|||
# type: (str) -> ValueType |
|||
if name in ValueType._registry: |
|||
return ValueType._registry[name] |
|||
else: |
|||
raise AttributeError("No type named '{}'".format(name)) |
|||
|
|||
|
|||
class ScalarType(ValueType): |
|||
""" |
|||
A concrete scalar (not vector) type. |
|||
|
|||
Also tracks a unique set of :py:class:`VectorType` instances with this type |
|||
as the lane type. |
|||
""" |
|||
|
|||
def __init__(self, name, membytes, doc): |
|||
# type: (str, int, str) -> None |
|||
super(ScalarType, self).__init__(name, membytes, doc) |
|||
self._vectors = dict() # type: Dict[int, VectorType] |
|||
# Assign numbers starting from 1. (0 is VOID). |
|||
ValueType.all_scalars.append(self) |
|||
self.number = len(ValueType.all_scalars) |
|||
assert self.number < 16, 'Too many scalar types' |
|||
|
|||
def __repr__(self): |
|||
# type: () -> str |
|||
return 'ScalarType({})'.format(self.name) |
|||
|
|||
def rust_name(self): |
|||
# type: () -> str |
|||
return 'types::' + self.name.upper() |
|||
|
|||
def by(self, lanes): |
|||
# type: (int) -> VectorType |
|||
""" |
|||
Get a vector type with this type as the lane type. |
|||
|
|||
For example, ``i32.by(4)`` returns the :obj:`i32x4` type. |
|||
""" |
|||
if lanes in self._vectors: |
|||
return self._vectors[lanes] |
|||
else: |
|||
v = VectorType(self, lanes) |
|||
self._vectors[lanes] = v |
|||
return v |
|||
|
|||
|
|||
class VectorType(ValueType): |
|||
""" |
|||
A concrete SIMD vector type. |
|||
|
|||
A vector type has a lane type which is an instance of :class:`ScalarType`, |
|||
and a positive number of lanes. |
|||
""" |
|||
|
|||
def __init__(self, base, lanes): |
|||
# type: (ScalarType, int) -> None |
|||
assert isinstance(base, ScalarType), 'SIMD lanes must be scalar types' |
|||
super(VectorType, self).__init__( |
|||
name='{}x{}'.format(base.name, lanes), |
|||
membytes=lanes*base.membytes, |
|||
doc=""" |
|||
A SIMD vector with {} lanes containing a `{}` each. |
|||
""".format(lanes, base.name)) |
|||
self.base = base |
|||
self.lanes = lanes |
|||
self.number = 16*int(math.log(lanes, 2)) + base.number |
|||
|
|||
def __repr__(self): |
|||
# type: () -> str |
|||
return ('VectorType(base={}, lanes={})' |
|||
.format(self.base.name, self.lanes)) |
|||
|
|||
|
|||
class IntType(ScalarType): |
|||
"""A concrete scalar integer type.""" |
|||
|
|||
def __init__(self, bits): |
|||
# type: (int) -> None |
|||
assert bits > 0, 'IntType must have positive number of bits' |
|||
super(IntType, self).__init__( |
|||
name='i{:d}'.format(bits), |
|||
membytes=bits // 8, |
|||
doc="An integer type with {} bits.".format(bits)) |
|||
self.bits = bits |
|||
|
|||
def __repr__(self): |
|||
# type: () -> str |
|||
return 'IntType(bits={})'.format(self.bits) |
|||
|
|||
|
|||
class FloatType(ScalarType): |
|||
"""A concrete scalar floating point type.""" |
|||
|
|||
def __init__(self, bits, doc): |
|||
# type: (int, str) -> None |
|||
assert bits > 0, 'FloatType must have positive number of bits' |
|||
super(FloatType, self).__init__( |
|||
name='f{:d}'.format(bits), |
|||
membytes=bits // 8, |
|||
doc=doc) |
|||
self.bits = bits |
|||
|
|||
def __repr__(self): |
|||
# type: () -> str |
|||
return 'FloatType(bits={})'.format(self.bits) |
|||
|
|||
|
|||
class BoolType(ScalarType): |
|||
"""A concrete scalar boolean type.""" |
|||
|
|||
def __init__(self, bits): |
|||
# type: (int) -> None |
|||
assert bits > 0, 'BoolType must have positive number of bits' |
|||
super(BoolType, self).__init__( |
|||
name='b{:d}'.format(bits), |
|||
membytes=bits // 8, |
|||
doc="A boolean type with {} bits.".format(bits)) |
|||
self.bits = bits |
|||
|
|||
def __repr__(self): |
|||
# type: () -> str |
|||
return 'BoolType(bits={})'.format(self.bits) |
Loading…
Reference in new issue