From 74625a9b7984c1aa83587feaf0bcc6d23fd9d927 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 18 May 2016 12:24:14 -0700 Subject: [PATCH] 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(). --- cranelift/docs/metaref.rst | 39 ++++++++++++++++++++++++++++++++++++++ meta/cretonne/__init__.py | 24 +++++++++++++++++++---- 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/cranelift/docs/metaref.rst b/cranelift/docs/metaref.rst index 2e47535492..5858ef512e 100644 --- a/cranelift/docs/metaref.rst +++ b/cranelift/docs/metaref.rst @@ -58,6 +58,7 @@ Polymorphism only works for SSA value operands. Immediate operands have a fixed operand kind. .. autoclass:: TypeVar + :members: 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 @@ -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 inputs. +There are some practical restrictions on the use of type variables, see +:ref:`restricted-polymorphism`. + Immediate operands ------------------ @@ -144,6 +148,41 @@ predefined instruction format which is an instance of .. 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 ======= diff --git a/meta/cretonne/__init__.py b/meta/cretonne/__init__.py index 7e6f61d6bf..8ce84394da 100644 --- a/meta/cretonne/__init__.py +++ b/meta/cretonne/__init__.py @@ -240,11 +240,27 @@ class TypeVar(object): self.name = name 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): - """ - 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. - """ + # 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