Add restrictions on polymorphism.

Also introduce the concept of a derived type variable, and provide two
methods for deriving type vars: lane() and as_bool().
This commit is contained in:
Jakob Stoklund Olesen
2016-05-18 12:24:14 -07:00
parent 639d92177a
commit 74625a9b79
2 changed files with 59 additions and 4 deletions

View File

@@ -58,6 +58,7 @@ Polymorphism only works for SSA value operands. Immediate operands have a fixed
operand kind. operand kind.
.. autoclass:: TypeVar .. autoclass:: TypeVar
: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
have the same concrete type. For example, this defines an integer addition have the same concrete type. For example, this defines an integer addition
@@ -75,6 +76,9 @@ value types, but in a given instance of the `iadd` instruction, the two
operands must have the same type, and the result will be the same type as the operands must have the same type, and the result will be the same type as the
inputs. inputs.
There are some practical restrictions on the use of type variables, see
:ref:`restricted-polymorphism`.
Immediate operands Immediate operands
------------------ ------------------
@@ -144,6 +148,41 @@ predefined instruction format which is an instance of
.. autoclass:: InstructionFormat .. autoclass:: InstructionFormat
.. _restricted-polymorphism:
Restricted polymorphism
-----------------------
The instruction format strictly controls the kinds of operands on an
instruction, but it does not constrain value types at all. A given instruction
description typically does constrain the allowed value types for its value
operands. The type variables give a lot of freedom in describing the value type
constraints, in practice more freedom than what is needed for normal instruction
set architectures. In order to simplify the Rust representation of value type
constraints, some restrictions are imposed on the use of type variables.
A polymorphic instruction has a single *controlling type variable*. The value
types of instruction results must be one of the following:
1. A concrete value type.
2. The controlling type variable.
3. A type variable derived from the controlling type variable.
This means that all result types can be computed from the controlling type
variable.
Input values to the instruction are allowed a bit more freedom. Input value
types must be one of:
1. A concrete value type.
2. The controlling type variable.
3. A type variable derived from the controlling type variable.
4. A free type variable that is not used by any other operands.
This means that the type of an input operand can either be computed from the
controlling type variable, or it can vary independently of the other operands.
Targets Targets
======= =======

View File

@@ -240,11 +240,27 @@ class TypeVar(object):
self.name = name self.name = name
self.__doc__ = doc self.__doc__ = doc
def lane(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("Lane type of " + self.name, '', base=self, simd=False)
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(self.name + " as boolean", '', base=self, bools=True)
def operand_kind(self): def operand_kind(self):
""" # When a `TypeVar` object is used to describe the type of an `Operand`
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
in an instruction definition, the kind of that operand is an SSA value. # value.
"""
return value return value